{"action":"created","comment":{"url":"https://api.github.com/repos/dotnet/roslyn/pulls/comments/66552970","id":66552970,"diff_hunk":"@@ -0,0 +1,324 @@\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 Microsoft.CodeAnalysis.CodeGen;\n+using Microsoft.CodeAnalysis.CSharp.Syntax;\n+using Microsoft.CodeAnalysis.CSharp.Symbols;\n+using Roslyn.Utilities;\n+using System.Collections.Immutable;\n+\n+namespace Microsoft.CodeAnalysis.CSharp\n+{\n+    /// <summary>\n+    /// This type provides means for instrumenting compiled methods for dynamic analysis.\n+    /// It can be combined with other <see cref=\"Instrumenter\"/>s.\n+    /// </summary>\n+    internal partial class DynamicAnalysisInjector : CompoundInstrumenter\n+    {\n+        private readonly bool _doInstrumentation;\n+        private readonly MethodSymbol _method;\n+        private readonly MethodSymbol _createPayload;\n+        private readonly ArrayBuilder<SourceSpan> _spansBuilder;\n+        private readonly ArrayTypeSymbol _payloadType;\n+        private readonly LocalSymbol _methodPayload;\n+        private readonly TypeCompilationState _compilationState;\n+        private readonly DiagnosticBag _diagnostics;\n+        private readonly DebugDocumentProvider _debugDocumentProvider;\n+        private readonly bool _methodHasExplicitBlock;\n+        private readonly SyntheticBoundNodeFactory _factory;\n+\n+        public DynamicAnalysisInjector(MethodSymbol method, BoundStatement methodBody, SyntheticBoundNodeFactory factory, TypeCompilationState compilationState, DiagnosticBag diagnostics, DebugDocumentProvider debugDocumentProvider, Instrumenter previous)\n+            : base (previous)\n+        {\n+            CSharpCompilation compilation = compilationState.Compilation;\n+            _createPayload = GetCreatePayload(compilation, methodBody.Syntax, diagnostics);\n+\n+            // Do not instrument the instrumentation helpers if they are part of the current compilation (which occurs only during testing). GetCreatePayload will fail with an infinite recursion if it is instrumented.\n+            // PROTOTYPE (https://github.com/dotnet/roslyn/issues/10266): It is not correct to always skip implict methods, because that will miss field initializers.\n+            if ((object)_createPayload != null && !method.IsImplicitlyDeclared && !method.Equals(_createPayload))\n+            {\n+                _doInstrumentation = true;\n+                _method = method;\n+                _spansBuilder = ArrayBuilder<SourceSpan>.GetInstance();\n+                TypeSymbol payloadElementType = factory.SpecialType(SpecialType.System_Boolean);\n+                _payloadType = ArrayTypeSymbol.CreateCSharpArray(compilation.Assembly, payloadElementType);\n+                _methodPayload = factory.SynthesizedLocal(_payloadType, kind: SynthesizedLocalKind.InstrumentationPayload, syntax: methodBody.Syntax); ;\n+                _compilationState = compilationState;\n+                _diagnostics = diagnostics;\n+                _debugDocumentProvider = debugDocumentProvider;\n+                _methodHasExplicitBlock = MethodHasExplicitBlock(method);\n+                _factory = factory;\n+            }\n+        }\n+\n+        public BoundStatement AddInstrumentationPrologue(BoundBlock rewrittenMethodBody, ref ImmutableArray<SourceSpan> dynamicAnalysisSpans)\n+        {\n+            if (_doInstrumentation)\n+            {\n+                dynamicAnalysisSpans = _spansBuilder.ToImmutableAndFree();\n+                // PROTOTYPE (https://github.com/dotnet/roslyn/issues/10411): In the future there will be multiple analysis kinds.\n+                const int analysisKind = 0;\n+\n+                ArrayTypeSymbol modulePayloadType = ArrayTypeSymbol.CreateCSharpArray(_compilationState.Compilation.Assembly, _payloadType);\n+\n+                // Synthesize the initialization of the instrumentation payload array, using concurrency-safe code:\n+                //\n+                // var payload = PID.PayloadRootField[methodIndex];\n+                // if (payload == null)\n+                //     payload = Instrumentation.CreatePayload(mvid, methodIndex, ref PID.PayloadRootField[methodIndex], payloadLength);\n+\n+                BoundStatement payloadInitialization = _factory.Assignment(_factory.Local(_methodPayload), _factory.ArrayAccess(_factory.InstrumentationPayloadRoot(analysisKind, modulePayloadType), ImmutableArray.Create(_factory.MethodDefIndex(_method))));\n+                BoundExpression mvid = _factory.ModuleVersionId();\n+                BoundExpression methodToken = _factory.MethodDefIndex(_method);\n+                BoundExpression payloadSlot = _factory.ArrayAccess(_factory.InstrumentationPayloadRoot(analysisKind, modulePayloadType), ImmutableArray.Create(_factory.MethodDefIndex(_method)));\n+                BoundStatement createPayloadCall = _factory.Assignment(_factory.Local(_methodPayload), _factory.Call(null, _createPayload, mvid, methodToken, payloadSlot, _factory.Literal(dynamicAnalysisSpans.Length)));\n+\n+                BoundExpression payloadNullTest = _factory.Binary(BinaryOperatorKind.ObjectEqual, _factory.SpecialType(SpecialType.System_Boolean), _factory.Local(_methodPayload), _factory.Null(_payloadType));\n+                BoundStatement payloadIf = _factory.If(payloadNullTest, createPayloadCall);\n+\n+                // There must be a sequence point before any executable code. A sequence point\n+                // won't be generated automatically for the synthesized prologue because the prologue is compiler generated, so\n+                // force the generation of a sequence point for the prologue.\n+                payloadInitialization = _factory.SequencePoint(payloadInitialization.Syntax, payloadInitialization);\n+\n+                ImmutableArray<BoundStatement> newStatements = ImmutableArray.Create<BoundStatement>(payloadInitialization, payloadIf).AddRange(rewrittenMethodBody.Statements);\n+                rewrittenMethodBody = rewrittenMethodBody.Update(rewrittenMethodBody.Locals.Add(_methodPayload), rewrittenMethodBody.LocalFunctions, newStatements);\n+            }\n+\n+            return rewrittenMethodBody;\n+        }\n+\n+        public override BoundStatement InstrumentNoOpStatement(BoundNoOpStatement original, BoundStatement rewritten)\n+        {\n+            return AddDynamicAnalysis(original, base.InstrumentNoOpStatement(original, rewritten));\n+        }\n+\n+        public override BoundStatement InstrumentBreakStatement(BoundBreakStatement original, BoundStatement rewritten)\n+        {\n+            return AddDynamicAnalysis(original, base.InstrumentBreakStatement(original, rewritten));\n+        }\n+\n+        public override BoundStatement InstrumentContinueStatement(BoundContinueStatement original, BoundStatement rewritten)\n+        {\n+            return AddDynamicAnalysis(original, base.InstrumentContinueStatement(original, rewritten));\n+        }\n+\n+        public override BoundStatement InstrumentExpressionStatement(BoundExpressionStatement original, BoundStatement rewritten)\n+        {\n+            rewritten = base.InstrumentExpressionStatement(original, rewritten);\n+\n+            if (!_methodHasExplicitBlock)\n+            {\n+                // The assignment statement for a property set method defined without a block is compiler generated, but requires instrumentation.\n+                return CollectDynamicAnalysis(original, rewritten);\n+            }\n+\n+            return AddDynamicAnalysis(original, rewritten);\n+        }\n+\n+        public override BoundStatement InstrumentFieldOrPropertyInitializer(BoundExpressionStatement original, BoundStatement rewritten)\n+        {\n+            rewritten = base.InstrumentExpressionStatement(original, rewritten);\n+            CSharpSyntaxNode syntax = original.Syntax;\n+\n+            switch (syntax.Parent.Parent.Kind())\n+            {\n+                case SyntaxKind.VariableDeclarator:\n+                case SyntaxKind.PropertyDeclaration:\n+                    return AddDynamicAnalysis(original, rewritten);\n+\n+                default:\n+                    throw ExceptionUtilities.UnexpectedValue(syntax.Parent.Parent.Kind());\n+            }\n+        }\n+\n+        public override BoundStatement InstrumentGotoStatement(BoundGotoStatement original, BoundStatement rewritten)\n+        {\n+            return AddDynamicAnalysis(original, base.InstrumentGotoStatement(original, rewritten));\n+        }\n+\n+        public override BoundStatement InstrumentThrowStatement(BoundThrowStatement original, BoundStatement rewritten)\n+        {\n+            return AddDynamicAnalysis(original, base.InstrumentThrowStatement(original, rewritten));\n+        }\n+\n+        public override BoundStatement InstrumentYieldBreakStatement(BoundYieldBreakStatement original, BoundStatement rewritten)\n+        {\n+            return AddDynamicAnalysis(original, base.InstrumentYieldBreakStatement(original, rewritten));\n+        }\n+\n+        public override BoundStatement InstrumentYieldReturnStatement(BoundYieldReturnStatement original, BoundStatement rewritten)\n+        {\n+            return AddDynamicAnalysis(original, base.InstrumentYieldReturnStatement(original, rewritten));\n+        }\n+\n+        public override BoundStatement InstrumentForEachStatementIterationVarDeclaration(BoundForEachStatement original, BoundStatement iterationVarDecl)\n+        {\n+            return AddDynamicAnalysis(original, base.InstrumentForEachStatementIterationVarDeclaration(original, iterationVarDecl));\n+        }\n+        \n+        public override BoundStatement InstrumentIfStatement(BoundIfStatement original, BoundStatement rewritten)\n+        {\n+            return AddDynamicAnalysis(original, base.InstrumentIfStatement(original, rewritten));\n+        }\n+\n+        public override BoundStatement InstrumentWhileStatementConditionalGotoStart(BoundWhileStatement original, BoundStatement ifConditionGotoStart)\n+        {\n+            return AddDynamicAnalysis(original, base.InstrumentWhileStatementConditionalGotoStart(original, ifConditionGotoStart));\n+        }\n+\n+        public override BoundStatement InstrumentLocalInitialization(BoundLocalDeclaration original, BoundStatement rewritten)\n+        {\n+            return AddDynamicAnalysis(original, base.InstrumentLocalInitialization(original, rewritten));\n+        }\n+\n+        public override BoundStatement InstrumentLockTargetCapture(BoundLockStatement original, BoundStatement lockTargetCapture)\n+        {\n+            return AddDynamicAnalysis(original, base.InstrumentLockTargetCapture(original, lockTargetCapture));\n+        }\n+\n+        public override BoundStatement InstrumentReturnStatement(BoundReturnStatement original, BoundStatement rewritten)\n+        {\n+            rewritten = base.InstrumentReturnStatement(original, rewritten);\n+\n+            // A synthesized return statement that does not return a value never requires instrumentation.\n+            // A property set method defined without a block has such a synthesized return statement.\n+            if (!_methodHasExplicitBlock && ((BoundReturnStatement)original).ExpressionOpt != null)\n+            {\n+                // The return statement for value-returning methods defined without a block is compiler generated, but requires instrumentation.\n+                return CollectDynamicAnalysis(original, rewritten);\n+            }\n+\n+            return AddDynamicAnalysis(original, rewritten);\n+        }\n+\n+        public override BoundStatement InstrumentSwitchStatement(BoundSwitchStatement original, BoundStatement rewritten)\n+        {\n+            return AddDynamicAnalysis(original, base.InstrumentSwitchStatement(original, rewritten));\n+        }\n+\n+        public override BoundStatement InstrumentUsingTargetCapture(BoundUsingStatement original, BoundStatement usingTargetCapture)\n+        {\n+            return AddDynamicAnalysis(original, base.InstrumentUsingTargetCapture(original, usingTargetCapture));\n+        }\n+        \n+        private BoundStatement AddDynamicAnalysis(BoundStatement original, BoundStatement rewritten)\n+        {\n+            if (!original.WasCompilerGenerated)\n+            {\n+                // Do not instrument implicit constructor initializers\n+                if (!original.IsConstructorInitializer() || original.Syntax.Kind() != SyntaxKind.ConstructorDeclaration)\n+                {\n+                    return CollectDynamicAnalysis(original, rewritten);\n+                }\n+            }\n+\n+            return rewritten;\n+        }\n+\n+        private BoundStatement CollectDynamicAnalysis(BoundStatement original, BoundStatement rewritten)\n+        {\n+            if (_doInstrumentation)\n+            {\n+                // Add an entry in the spans array.\n+\n+                CSharpSyntaxNode syntaxForSpan = SyntaxForSpan(original);\n+                Location location = syntaxForSpan.GetLocation();\n+                FileLinePositionSpan spanPosition = location.GetMappedLineSpan();\n+                string path = spanPosition.Path;\n+                if (path.Length == 0)\n+                {\n+                    path = syntaxForSpan.SyntaxTree.FilePath;\n+                }\n+\n+                int spansIndex = _spansBuilder.Count;\n+                _spansBuilder.Add(new SourceSpan(_debugDocumentProvider.Invoke(path, \"\"), spanPosition.StartLinePosition.Line, spanPosition.StartLinePosition.Character, spanPosition.EndLinePosition.Line, spanPosition.EndLinePosition.Character));\n+\n+                // Generate \"_payload[pointIndex] = true\".\n+\n+                SyntheticBoundNodeFactory statementFactory = new SyntheticBoundNodeFactory(_method, rewritten.Syntax, _compilationState, _diagnostics);\n+                BoundArrayAccess payloadCell = statementFactory.ArrayAccess(statementFactory.Local(_methodPayload), statementFactory.Literal(spansIndex));\n+                BoundExpressionStatement cellAssignment = statementFactory.Assignment(payloadCell, statementFactory.Literal(true));\n+\n+                return statementFactory.Block(ImmutableArray.Create(cellAssignment, rewritten));\n+            }\n+\n+            return rewritten;\n+        }\n+\n+        private static CSharpSyntaxNode SyntaxForSpan(BoundStatement statement)\n+        {\n+            CSharpSyntaxNode syntaxForSpan;\n+\n+            switch (statement.Kind)\n+            {\n+                case BoundKind.IfStatement:\n+                    syntaxForSpan = ((BoundIfStatement)statement).Condition.Syntax;\n+                    break;\n+                case BoundKind.WhileStatement:\n+                    syntaxForSpan = ((BoundWhileStatement)statement).Condition.Syntax;\n+                    break;\n+                case BoundKind.ForEachStatement:\n+                    // PROTOTYPE (https://github.com/dotnet/roslyn/issues/10141): Also include the declaration of the loop variable in the span.\n+                    syntaxForSpan = ((BoundForEachStatement)statement).Expression.Syntax;\n+                    break;\n+                case BoundKind.DoStatement:\n+                    syntaxForSpan = ((BoundDoStatement)statement).Condition.Syntax;\n+                    break;\n+                case BoundKind.UsingStatement:\n+                    {\n+                        BoundUsingStatement usingStatement = (BoundUsingStatement)statement;\n+                        syntaxForSpan = ((BoundNode)usingStatement.ExpressionOpt ?? usingStatement.DeclarationsOpt).Syntax;\n+                        break;\n+                    }\n+                case BoundKind.FixedStatement:\n+                    syntaxForSpan = ((BoundFixedStatement)statement).Declarations.Syntax;\n+                    break;\n+                case BoundKind.LockStatement:\n+                    syntaxForSpan = ((BoundLockStatement)statement).Argument.Syntax;\n+                    break;\n+                case BoundKind.SwitchStatement:\n+                    syntaxForSpan = ((BoundSwitchStatement)statement).Expression.Syntax;\n+                    break;\n+                default:\n+                    syntaxForSpan = statement.Syntax;\n+                    break;\n+            }\n+\n+            return syntaxForSpan;\n+        }\n+\n+        private static bool HasInitializer(BoundLocalDeclaration local)\n+        {\n+            return local.InitializerOpt != null;\n+        }\n+\n+        private static bool HasInitializer(BoundMultipleLocalDeclarations multiple)\n+        {\n+            foreach (BoundLocalDeclaration local in multiple.LocalDeclarations)\n+            {\n+                if (HasInitializer(local))\n+                {\n+                    return true;\n+                }\n+            }\n+\n+            return false;\n+        }\n+\n+        private static bool MethodHasExplicitBlock(MethodSymbol method)\n+        {\n+            SourceMethodSymbol asSourceMethod = method.ConstructedFrom as SourceMethodSymbol;","path":"src/Compilers/CSharp/Portable/Lowering/Instrumentation/DynamicAnalysisInjector.cs","position":310,"original_position":310,"commit_id":"5a81d917c4c1cec0742fa6426d567b339765ec10","original_commit_id":"5a81d917c4c1cec0742fa6426d567b339765ec10","user":{"login":"JohnHamby","id":10982715,"avatar_url":"https://avatars.githubusercontent.com/u/10982715?v=3","gravatar_id":"","url":"https://api.github.com/users/JohnHamby","html_url":"https://github.com/JohnHamby","followers_url":"https://api.github.com/users/JohnHamby/followers","following_url":"https://api.github.com/users/JohnHamby/following{/other_user}","gists_url":"https://api.github.com/users/JohnHamby/gists{/gist_id}","starred_url":"https://api.github.com/users/JohnHamby/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/JohnHamby/subscriptions","organizations_url":"https://api.github.com/users/JohnHamby/orgs","repos_url":"https://api.github.com/users/JohnHamby/repos","events_url":"https://api.github.com/users/JohnHamby/events{/privacy}","received_events_url":"https://api.github.com/users/JohnHamby/received_events","type":"User","site_admin":false},"body":"Yes.","created_at":"2016-06-10T02:14:47Z","updated_at":"2016-06-10T02:14:47Z","html_url":"https://github.com/dotnet/roslyn/pull/11884#discussion_r66552970","pull_request_url":"https://api.github.com/repos/dotnet/roslyn/pulls/11884","_links":{"self":{"href":"https://api.github.com/repos/dotnet/roslyn/pulls/comments/66552970"},"html":{"href":"https://github.com/dotnet/roslyn/pull/11884#discussion_r66552970"},"pull_request":{"href":"https://api.github.com/repos/dotnet/roslyn/pulls/11884"}}},"pull_request":{"url":"https://api.github.com/repos/dotnet/roslyn/pulls/11884","id":73167524,"html_url":"https://github.com/dotnet/roslyn/pull/11884","diff_url":"https://github.com/dotnet/roslyn/pull/11884.diff","patch_url":"https://github.com/dotnet/roslyn/pull/11884.patch","issue_url":"https://api.github.com/repos/dotnet/roslyn/issues/11884","number":11884,"state":"open","locked":false,"title":"Incorporate dynamic analysis instrumentation into LocalRewriter","user":{"login":"JohnHamby","id":10982715,"avatar_url":"https://avatars.githubusercontent.com/u/10982715?v=3","gravatar_id":"","url":"https://api.github.com/users/JohnHamby","html_url":"https://github.com/JohnHamby","followers_url":"https://api.github.com/users/JohnHamby/followers","following_url":"https://api.github.com/users/JohnHamby/following{/other_user}","gists_url":"https://api.github.com/users/JohnHamby/gists{/gist_id}","starred_url":"https://api.github.com/users/JohnHamby/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/JohnHamby/subscriptions","organizations_url":"https://api.github.com/users/JohnHamby/orgs","repos_url":"https://api.github.com/users/JohnHamby/repos","events_url":"https://api.github.com/users/JohnHamby/events{/privacy}","received_events_url":"https://api.github.com/users/JohnHamby/received_events","type":"User","site_admin":false},"body":"This change set removes the dynamic analysis instrumentation pass, replacing it with instrumentation injection during local rewriting.\r\n\r\nThanks @AlekseyTs for providing such a nice platform for this!\r\n\r\nReview solicited from @dotnet/roslyn-compiler @dotnet/testimpact @jcouv @AlekseyTs @genlu @tmat @ManishJayaswal ","created_at":"2016-06-09T07:20:00Z","updated_at":"2016-06-10T02:14:47Z","closed_at":null,"merged_at":null,"merge_commit_sha":"f4e05552a1e187abf53463e4bc2a0d9fe459e113","assignee":null,"milestone":null,"commits_url":"https://api.github.com/repos/dotnet/roslyn/pulls/11884/commits","review_comments_url":"https://api.github.com/repos/dotnet/roslyn/pulls/11884/comments","review_comment_url":"https://api.github.com/repos/dotnet/roslyn/pulls/comments{/number}","comments_url":"https://api.github.com/repos/dotnet/roslyn/issues/11884/comments","statuses_url":"https://api.github.com/repos/dotnet/roslyn/statuses/5a81d917c4c1cec0742fa6426d567b339765ec10","head":{"label":"JohnHamby:InstrumentationRewrite","ref":"InstrumentationRewrite","sha":"5a81d917c4c1cec0742fa6426d567b339765ec10","user":{"login":"JohnHamby","id":10982715,"avatar_url":"https://avatars.githubusercontent.com/u/10982715?v=3","gravatar_id":"","url":"https://api.github.com/users/JohnHamby","html_url":"https://github.com/JohnHamby","followers_url":"https://api.github.com/users/JohnHamby/followers","following_url":"https://api.github.com/users/JohnHamby/following{/other_user}","gists_url":"https://api.github.com/users/JohnHamby/gists{/gist_id}","starred_url":"https://api.github.com/users/JohnHamby/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/JohnHamby/subscriptions","organizations_url":"https://api.github.com/users/JohnHamby/orgs","repos_url":"https://api.github.com/users/JohnHamby/repos","events_url":"https://api.github.com/users/JohnHamby/events{/privacy}","received_events_url":"https://api.github.com/users/JohnHamby/received_events","type":"User","site_admin":false},"repo":{"id":30732063,"name":"roslyn","full_name":"JohnHamby/roslyn","owner":{"login":"JohnHamby","id":10982715,"avatar_url":"https://avatars.githubusercontent.com/u/10982715?v=3","gravatar_id":"","url":"https://api.github.com/users/JohnHamby","html_url":"https://github.com/JohnHamby","followers_url":"https://api.github.com/users/JohnHamby/followers","following_url":"https://api.github.com/users/JohnHamby/following{/other_user}","gists_url":"https://api.github.com/users/JohnHamby/gists{/gist_id}","starred_url":"https://api.github.com/users/JohnHamby/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/JohnHamby/subscriptions","organizations_url":"https://api.github.com/users/JohnHamby/orgs","repos_url":"https://api.github.com/users/JohnHamby/repos","events_url":"https://api.github.com/users/JohnHamby/events{/privacy}","received_events_url":"https://api.github.com/users/JohnHamby/received_events","type":"User","site_admin":false},"private":false,"html_url":"https://github.com/JohnHamby/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/JohnHamby/roslyn","forks_url":"https://api.github.com/repos/JohnHamby/roslyn/forks","keys_url":"https://api.github.com/repos/JohnHamby/roslyn/keys{/key_id}","collaborators_url":"https://api.github.com/repos/JohnHamby/roslyn/collaborators{/collaborator}","teams_url":"https://api.github.com/repos/JohnHamby/roslyn/teams","hooks_url":"https://api.github.com/repos/JohnHamby/roslyn/hooks","issue_events_url":"https://api.github.com/repos/JohnHamby/roslyn/issues/events{/number}","events_url":"https://api.github.com/repos/JohnHamby/roslyn/events","assignees_url":"https://api.github.com/repos/JohnHamby/roslyn/assignees{/user}","branches_url":"https://api.github.com/repos/JohnHamby/roslyn/branches{/branch}","tags_url":"https://api.github.com/repos/JohnHamby/roslyn/tags","blobs_url":"https://api.github.com/repos/JohnHamby/roslyn/git/blobs{/sha}","git_tags_url":"https://api.github.com/repos/JohnHamby/roslyn/git/tags{/sha}","git_refs_url":"https://api.github.com/repos/JohnHamby/roslyn/git/refs{/sha}","trees_url":"https://api.github.com/repos/JohnHamby/roslyn/git/trees{/sha}","statuses_url":"https://api.github.com/repos/JohnHamby/roslyn/statuses/{sha}","languages_url":"https://api.github.com/repos/JohnHamby/roslyn/languages","stargazers_url":"https://api.github.com/repos/JohnHamby/roslyn/stargazers","contributors_url":"https://api.github.com/repos/JohnHamby/roslyn/contributors","subscribers_url":"https://api.github.com/repos/JohnHamby/roslyn/subscribers","subscription_url":"https://api.github.com/repos/JohnHamby/roslyn/subscription","commits_url":"https://api.github.com/repos/JohnHamby/roslyn/commits{/sha}","git_commits_url":"https://api.github.com/repos/JohnHamby/roslyn/git/commits{/sha}","comments_url":"https://api.github.com/repos/JohnHamby/roslyn/comments{/number}","issue_comment_url":"https://api.github.com/repos/JohnHamby/roslyn/issues/comments{/number}","contents_url":"https://api.github.com/repos/JohnHamby/roslyn/contents/{+path}","compare_url":"https://api.github.com/repos/JohnHamby/roslyn/compare/{base}...{head}","merges_url":"https://api.github.com/repos/JohnHamby/roslyn/merges","archive_url":"https://api.github.com/repos/JohnHamby/roslyn/{archive_format}{/ref}","downloads_url":"https://api.github.com/repos/JohnHamby/roslyn/downloads","issues_url":"https://api.github.com/repos/JohnHamby/roslyn/issues{/number}","pulls_url":"https://api.github.com/repos/JohnHamby/roslyn/pulls{/number}","milestones_url":"https://api.github.com/repos/JohnHamby/roslyn/milestones{/number}","notifications_url":"https://api.github.com/repos/JohnHamby/roslyn/notifications{?since,all,participating}","labels_url":"https://api.github.com/repos/JohnHamby/roslyn/labels{/name}","releases_url":"https://api.github.com/repos/JohnHamby/roslyn/releases{/id}","deployments_url":"https://api.github.com/repos/JohnHamby/roslyn/deployments","created_at":"2015-02-13T00:07:31Z","updated_at":"2015-02-13T00:07:58Z","pushed_at":"2016-06-09T07:15:58Z","git_url":"git://github.com/JohnHamby/roslyn.git","ssh_url":"git@github.com:JohnHamby/roslyn.git","clone_url":"https://github.com/JohnHamby/roslyn.git","svn_url":"https://github.com/JohnHamby/roslyn","homepage":"","size":161228,"stargazers_count":0,"watchers_count":0,"language":"C#","has_issues":false,"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:features/test-impact","ref":"features/test-impact","sha":"84d68a293b6b4c3871a11fa6133ed10ea7f59530","user":{"login":"dotnet","id":9141961,"avatar_url":"https://avatars.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://avatars.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":"2016-06-09T22:43:54Z","pushed_at":"2016-06-10T02:02:09Z","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":303137,"stargazers_count":5330,"watchers_count":5330,"language":"C#","has_issues":true,"has_downloads":true,"has_wiki":true,"has_pages":false,"forks_count":1327,"mirror_url":null,"open_issues_count":2917,"forks":1327,"open_issues":2917,"watchers":5330,"default_branch":"master"}},"_links":{"self":{"href":"https://api.github.com/repos/dotnet/roslyn/pulls/11884"},"html":{"href":"https://github.com/dotnet/roslyn/pull/11884"},"issue":{"href":"https://api.github.com/repos/dotnet/roslyn/issues/11884"},"comments":{"href":"https://api.github.com/repos/dotnet/roslyn/issues/11884/comments"},"review_comments":{"href":"https://api.github.com/repos/dotnet/roslyn/pulls/11884/comments"},"review_comment":{"href":"https://api.github.com/repos/dotnet/roslyn/pulls/comments{/number}"},"commits":{"href":"https://api.github.com/repos/dotnet/roslyn/pulls/11884/commits"},"statuses":{"href":"https://api.github.com/repos/dotnet/roslyn/statuses/5a81d917c4c1cec0742fa6426d567b339765ec10"}}}}
{"actor":{"display_login":"JohnHamby"}}