{"action":"created","comment":{"url":"https://api.github.com/repos/dotnet/roslyn/pulls/comments/122189295","pull_request_review_id":44280465,"id":122189295,"diff_hunk":"@@ -0,0 +1,161 @@\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.Collections.Immutable;\n+using Microsoft.CodeAnalysis.CodeStyle;\n+using Microsoft.CodeAnalysis.CSharp.Extensions;\n+using Microsoft.CodeAnalysis.CSharp.Syntax;\n+using Microsoft.CodeAnalysis.Diagnostics;\n+using Microsoft.CodeAnalysis.Text;\n+using Microsoft.CodeAnalysis.Utilities;\n+using Roslyn.Utilities;\n+\n+namespace Microsoft.CodeAnalysis.CSharp.RemoveUnreachableCode\n+{\n+    [DiagnosticAnalyzer(LanguageNames.CSharp)]\n+    internal class CSharpRemoveUnreachableCodeDiagnosticAnalyzer : AbstractCodeStyleDiagnosticAnalyzer\n+    {\n+        private const string CS0162 = nameof(CS0162); // Unreachable code detected\n+\n+        public const string IsCascadedSection = nameof(IsCascadedSection);\n+        private static readonly ImmutableDictionary<string, string> s_additionalProperties = ImmutableDictionary<string, string>.Empty.Add(IsCascadedSection, \"\");\n+\n+        public CSharpRemoveUnreachableCodeDiagnosticAnalyzer()\n+            : base(IDEDiagnosticIds.RemoveUnreachableCodeDiagnosticId,\n+                   new LocalizableResourceString(nameof(FeaturesResources.Unreachable_code_detected), FeaturesResources.ResourceManager, typeof(FeaturesResources)))\n+        {\n+        }\n+\n+        public override DiagnosticAnalyzerCategory GetAnalyzerCategory()\n+            => DiagnosticAnalyzerCategory.SemanticSpanAnalysis;\n+\n+        public override bool OpenFileOnly(Workspace workspace)\n+            => false;\n+\n+        protected override void InitializeWorker(AnalysisContext context)\n+            => context.RegisterSyntaxNodeAction(AnalyzeBlock, ImmutableArray.Create(SyntaxKind.Block));\n+\n+        private void AnalyzeBlock(SyntaxNodeAnalysisContext context)\n+        {\n+            var block = context.Node;\n+            if (!IsOutermostBlock(block))\n+            {\n+                // Don't bother processing inner blocks.  We'll have already checked them when\n+                // we processed the outer block\n+                return;\n+            }\n+\n+            var semanticModel = context.SemanticModel;\n+            var cancellationToken = context.CancellationToken;\n+\n+            // There is no good existing API to check if a statement is unreachable in an efficient\n+            // manner.  While there is SemanticModel.AnalyzeControlFlow, it can only operate on a \n+            // statement at a time, and it will reanalyze and allocate on each call.  \n+            //\n+            // To avoid this, we simply ask the semantic model for all the diagnostics for this\n+            // block and we look for any reported \"unreachable code detected\" diagnostics.\n+            //\n+            // This is actually quite fast to do because the compiler does not actually need to\n+            // recompile things to determine the diagnostics.  It will have already stashed the\n+            // binding diagnostics directly on the SourceMethodSymbol containing this block, and\n+            // so it can retrieve the diagnostics at practically no cost.\n+            var root = semanticModel.SyntaxTree.GetRoot(cancellationToken);\n+            var diagnostics = semanticModel.GetDiagnostics(block.Span, cancellationToken);\n+            foreach (var diagnostic in diagnostics)\n+            {\n+                cancellationToken.ThrowIfCancellationRequested();\n+\n+                if (diagnostic.Id == CS0162)\n+                {\n+                    ProcessUnreachableDiagnostic(context, root, diagnostic.Location.SourceSpan);\n+                }\n+            }\n+        }\n+\n+        private bool IsOutermostBlock(SyntaxNode block)\n+        {\n+            // Avoid linq/allocations as we will be calling this on every block in the solution.\n+            for (var current = block.Parent; current != null; current = current.Parent)\n+            {\n+                if (current.Kind() == SyntaxKind.Block)\n+                {\n+                    return false;\n+                }\n+            }\n+\n+            return true;\n+        }\n+\n+        private void ProcessUnreachableDiagnostic(\n+            SyntaxNodeAnalysisContext context, SyntaxNode root, TextSpan sourceSpan)\n+        {\n+            var node = root.FindNode(sourceSpan);\n+\n+            // Note: this approach works as the language only supports the concept of ","path":"src/Features/CSharp/Portable/RemoveUnreachableCode/CSharpRemoveUnreachableCodeDiagnosticAnalyzer.cs","position":98,"original_position":93,"commit_id":"40303e9a7a42ae30af59e66524f09bcd00845300","original_commit_id":"bdb37bb3124106cebd703e34fc147b07c2a49812","user":{"login":"sharwell","id":1408396,"avatar_url":"https://avatars2.githubusercontent.com/u/1408396?v=3","gravatar_id":"","url":"https://api.github.com/users/sharwell","html_url":"https://github.com/sharwell","followers_url":"https://api.github.com/users/sharwell/followers","following_url":"https://api.github.com/users/sharwell/following{/other_user}","gists_url":"https://api.github.com/users/sharwell/gists{/gist_id}","starred_url":"https://api.github.com/users/sharwell/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/sharwell/subscriptions","organizations_url":"https://api.github.com/users/sharwell/orgs","repos_url":"https://api.github.com/users/sharwell/repos","events_url":"https://api.github.com/users/sharwell/events{/privacy}","received_events_url":"https://api.github.com/users/sharwell/received_events","type":"User","site_admin":false},"body":":bulb: Maybe move this comment inside the block to the `return` statement. Also:\r\n\r\n1. The code is not incorrect even if subexpression reachability analysis was reported as CS0162, or even if the analyzer was modified to listen for something other than CS0162. If the beginning of a statement is unreachable, then the statement as a whole is also necessarily unreachable.\r\n1. This diagnostic is currently triggered by CS0162, but the limitation is only for the sake of convenience. Implementation of reachability for subexpressions in this analyzer is not, for example, blocked on dotnet/csharplang#664. In other words, if you refer to the currently limiting factor, mention it as CS0162 and not \"the language\".\r\n","created_at":"2017-06-15T12:22:16Z","updated_at":"2017-06-15T12:45:31Z","html_url":"https://github.com/dotnet/roslyn/pull/20236#discussion_r122189295","pull_request_url":"https://api.github.com/repos/dotnet/roslyn/pulls/20236","_links":{"self":{"href":"https://api.github.com/repos/dotnet/roslyn/pulls/comments/122189295"},"html":{"href":"https://github.com/dotnet/roslyn/pull/20236#discussion_r122189295"},"pull_request":{"href":"https://api.github.com/repos/dotnet/roslyn/pulls/20236"}}},"pull_request":{"url":"https://api.github.com/repos/dotnet/roslyn/pulls/20236","id":125805902,"html_url":"https://github.com/dotnet/roslyn/pull/20236","diff_url":"https://github.com/dotnet/roslyn/pull/20236.diff","patch_url":"https://github.com/dotnet/roslyn/pull/20236.patch","issue_url":"https://api.github.com/repos/dotnet/roslyn/issues/20236","number":20236,"state":"open","locked":false,"title":"Fade out unreachable code, and provide code-fix to remove unreachable code.","user":{"login":"CyrusNajmabadi","id":4564579,"avatar_url":"https://avatars0.githubusercontent.com/u/4564579?v=3","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":"Fixes https://github.com/dotnet/roslyn/issues/6970","created_at":"2017-06-15T12:02:51Z","updated_at":"2017-06-15T12:45:32Z","closed_at":null,"merged_at":null,"merge_commit_sha":"532960e72f98ce079765245e646224ccba9d1c2d","assignee":null,"assignees":[],"requested_reviewers":[],"milestone":null,"commits_url":"https://api.github.com/repos/dotnet/roslyn/pulls/20236/commits","review_comments_url":"https://api.github.com/repos/dotnet/roslyn/pulls/20236/comments","review_comment_url":"https://api.github.com/repos/dotnet/roslyn/pulls/comments{/number}","comments_url":"https://api.github.com/repos/dotnet/roslyn/issues/20236/comments","statuses_url":"https://api.github.com/repos/dotnet/roslyn/statuses/40303e9a7a42ae30af59e66524f09bcd00845300","head":{"label":"CyrusNajmabadi:removeUnreachableCode","ref":"removeUnreachableCode","sha":"40303e9a7a42ae30af59e66524f09bcd00845300","user":{"login":"CyrusNajmabadi","id":4564579,"avatar_url":"https://avatars0.githubusercontent.com/u/4564579?v=3","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},"repo":{"id":30565155,"name":"roslyn","full_name":"CyrusNajmabadi/roslyn","owner":{"login":"CyrusNajmabadi","id":4564579,"avatar_url":"https://avatars0.githubusercontent.com/u/4564579?v=3","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},"private":false,"html_url":"https://github.com/CyrusNajmabadi/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/CyrusNajmabadi/roslyn","forks_url":"https://api.github.com/repos/CyrusNajmabadi/roslyn/forks","keys_url":"https://api.github.com/repos/CyrusNajmabadi/roslyn/keys{/key_id}","collaborators_url":"https://api.github.com/repos/CyrusNajmabadi/roslyn/collaborators{/collaborator}","teams_url":"https://api.github.com/repos/CyrusNajmabadi/roslyn/teams","hooks_url":"https://api.github.com/repos/CyrusNajmabadi/roslyn/hooks","issue_events_url":"https://api.github.com/repos/CyrusNajmabadi/roslyn/issues/events{/number}","events_url":"https://api.github.com/repos/CyrusNajmabadi/roslyn/events","assignees_url":"https://api.github.com/repos/CyrusNajmabadi/roslyn/assignees{/user}","branches_url":"https://api.github.com/repos/CyrusNajmabadi/roslyn/branches{/branch}","tags_url":"https://api.github.com/repos/CyrusNajmabadi/roslyn/tags","blobs_url":"https://api.github.com/repos/CyrusNajmabadi/roslyn/git/blobs{/sha}","git_tags_url":"https://api.github.com/repos/CyrusNajmabadi/roslyn/git/tags{/sha}","git_refs_url":"https://api.github.com/repos/CyrusNajmabadi/roslyn/git/refs{/sha}","trees_url":"https://api.github.com/repos/CyrusNajmabadi/roslyn/git/trees{/sha}","statuses_url":"https://api.github.com/repos/CyrusNajmabadi/roslyn/statuses/{sha}","languages_url":"https://api.github.com/repos/CyrusNajmabadi/roslyn/languages","stargazers_url":"https://api.github.com/repos/CyrusNajmabadi/roslyn/stargazers","contributors_url":"https://api.github.com/repos/CyrusNajmabadi/roslyn/contributors","subscribers_url":"https://api.github.com/repos/CyrusNajmabadi/roslyn/subscribers","subscription_url":"https://api.github.com/repos/CyrusNajmabadi/roslyn/subscription","commits_url":"https://api.github.com/repos/CyrusNajmabadi/roslyn/commits{/sha}","git_commits_url":"https://api.github.com/repos/CyrusNajmabadi/roslyn/git/commits{/sha}","comments_url":"https://api.github.com/repos/CyrusNajmabadi/roslyn/comments{/number}","issue_comment_url":"https://api.github.com/repos/CyrusNajmabadi/roslyn/issues/comments{/number}","contents_url":"https://api.github.com/repos/CyrusNajmabadi/roslyn/contents/{+path}","compare_url":"https://api.github.com/repos/CyrusNajmabadi/roslyn/compare/{base}...{head}","merges_url":"https://api.github.com/repos/CyrusNajmabadi/roslyn/merges","archive_url":"https://api.github.com/repos/CyrusNajmabadi/roslyn/{archive_format}{/ref}","downloads_url":"https://api.github.com/repos/CyrusNajmabadi/roslyn/downloads","issues_url":"https://api.github.com/repos/CyrusNajmabadi/roslyn/issues{/number}","pulls_url":"https://api.github.com/repos/CyrusNajmabadi/roslyn/pulls{/number}","milestones_url":"https://api.github.com/repos/CyrusNajmabadi/roslyn/milestones{/number}","notifications_url":"https://api.github.com/repos/CyrusNajmabadi/roslyn/notifications{?since,all,participating}","labels_url":"https://api.github.com/repos/CyrusNajmabadi/roslyn/labels{/name}","releases_url":"https://api.github.com/repos/CyrusNajmabadi/roslyn/releases{/id}","deployments_url":"https://api.github.com/repos/CyrusNajmabadi/roslyn/deployments","created_at":"2015-02-09T23:45:22Z","updated_at":"2016-01-11T20:46:56Z","pushed_at":"2017-06-15T12:38:39Z","git_url":"git://github.com/CyrusNajmabadi/roslyn.git","ssh_url":"git@github.com:CyrusNajmabadi/roslyn.git","clone_url":"https://github.com/CyrusNajmabadi/roslyn.git","svn_url":"https://github.com/CyrusNajmabadi/roslyn","homepage":"","size":210422,"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,"open_issues_count":0,"forks":0,"open_issues":0,"watchers":0,"default_branch":"master"}},"base":{"label":"dotnet:dev15.6","ref":"dev15.6","sha":"0c6e2373fd25f89b87a605dc84c5141141300739","user":{"login":"dotnet","id":9141961,"avatar_url":"https://avatars3.githubusercontent.com/u/9141961?v=3","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,"name":"roslyn","full_name":"dotnet/roslyn","owner":{"login":"dotnet","id":9141961,"avatar_url":"https://avatars3.githubusercontent.com/u/9141961?v=3","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},"private":false,"html_url":"https://github.com/dotnet/roslyn","description":"The .NET Compiler Platform (\"Roslyn\") provides open-source C# and Visual Basic compilers 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":"2017-06-15T09:21:57Z","pushed_at":"2017-06-15T12:39:29Z","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":"","size":215494,"stargazers_count":7631,"watchers_count":7631,"language":"C#","has_issues":true,"has_projects":true,"has_downloads":true,"has_wiki":true,"has_pages":false,"forks_count":1872,"mirror_url":null,"open_issues_count":3723,"forks":1872,"open_issues":3723,"watchers":7631,"default_branch":"master"}},"_links":{"self":{"href":"https://api.github.com/repos/dotnet/roslyn/pulls/20236"},"html":{"href":"https://github.com/dotnet/roslyn/pull/20236"},"issue":{"href":"https://api.github.com/repos/dotnet/roslyn/issues/20236"},"comments":{"href":"https://api.github.com/repos/dotnet/roslyn/issues/20236/comments"},"review_comments":{"href":"https://api.github.com/repos/dotnet/roslyn/pulls/20236/comments"},"review_comment":{"href":"https://api.github.com/repos/dotnet/roslyn/pulls/comments{/number}"},"commits":{"href":"https://api.github.com/repos/dotnet/roslyn/pulls/20236/commits"},"statuses":{"href":"https://api.github.com/repos/dotnet/roslyn/statuses/40303e9a7a42ae30af59e66524f09bcd00845300"}}}}
{"actor":{"display_login":"sharwell"}}