{"action":"created","comment":{"url":"https://api.github.com/repos/sebastienros/esprima-dotnet/pulls/comments/245011874","pull_request_review_id":189026543,"id":245011874,"node_id":"MDI0OlB1bGxSZXF1ZXN0UmV2aWV3Q29tbWVudDI0NTAxMTg3NA==","diff_hunk":"@@ -0,0 +1,830 @@\n+﻿using System;\n+using System.Collections;\n+using System.Collections.Generic;\n+using System.Globalization;\n+using System.IO;\n+using System.Linq;\n+using System.Reflection;\n+using System.Runtime.CompilerServices;\n+using System.Text.RegularExpressions;\n+using Esprima.Ast;\n+\n+namespace Esprima.Utils\n+{\n+    public enum LocationMembersPlacement\n+    {\n+        End,\n+        Start,\n+    }\n+\n+    public static class AstJson\n+    {\n+        public sealed class Options\n+        {\n+            public static readonly Options Default = new Options();\n+\n+            public bool IncludeLineColumn { get; private set; }\n+            public bool IncludeRange { get; private set; }\n+            public LocationMembersPlacement LocationMembersPlacement { get; private set; }\n+\n+            public Options() {}\n+\n+            Options(Options options)\n+            {\n+                IncludeLineColumn = options.IncludeLineColumn;\n+                IncludeRange = options.IncludeRange;\n+                LocationMembersPlacement = options.LocationMembersPlacement;\n+            }\n+\n+            public Options WithIncludeLineColumn(bool value) =>\n+                value == IncludeLineColumn ? this : new Options(this) { IncludeLineColumn = value };\n+\n+            public Options WithIncludeRange(bool value) =>\n+                value == IncludeRange ? this : new Options(this) { IncludeRange = value };\n+\n+            public Options WithLocationMembersPlacement(LocationMembersPlacement value) =>\n+                value == LocationMembersPlacement ? this : new Options(this) { LocationMembersPlacement = value };\n+\n+            public Options WithLineColumn() => WithIncludeLineColumn(true);\n+            public Options WithRange()      => WithIncludeRange(true);\n+            public Options WithLocation()   => WithLineColumn().WithRange();\n+\n+            public Options WithLocation(LocationMembersPlacement placement) =>\n+                WithLocation().WithLocationMembersPlacement(placement);\n+        }\n+\n+        public static string ToJsonString(this INode node) =>\n+            ToJsonString(node, indent: null);\n+\n+        public static string ToJsonString(this INode node, string indent) =>\n+            ToJsonString(node, Options.Default, indent);\n+\n+        public static string ToJsonString(this INode node, Options options) =>\n+            ToJsonString(node, options, null);\n+\n+        public static string ToJsonString(this INode node, Options options, string indent)\n+        {\n+            var writer = new StringWriter();\n+            WriteJson(node, writer, options, indent);\n+            return writer.ToString();\n+        }\n+\n+        public static void WriteJson(this INode node, TextWriter writer) =>\n+            WriteJson(node, writer, indent: null);\n+\n+        public static void WriteJson(this INode node, TextWriter writer, string indent) =>\n+            WriteJson(node, writer, Options.Default, indent);\n+\n+        public static void WriteJson(this INode node, TextWriter writer, Options options) =>\n+            WriteJson(node, writer, options, null);\n+\n+        public static void WriteJson(this INode node, TextWriter writer, Options options, string indent)\n+        {\n+            if (node == null) throw new ArgumentNullException(nameof(node));\n+            if (writer == null) throw new ArgumentNullException(nameof(writer));\n+            if (options == null) throw new ArgumentNullException(nameof(options));\n+\n+            var visitor = new Visitor(new JsonTextWriter(writer, indent),\n+                                      options.IncludeLineColumn, options.IncludeRange,\n+                                      options.LocationMembersPlacement);\n+\n+            visitor.Visit(node);\n+        }\n+\n+        public static void WriteJson(this INode node, JsonWriter writer, Options options)\n+        {\n+            if (node == null) throw new ArgumentNullException(nameof(node));\n+            if (writer == null) throw new ArgumentNullException(nameof(writer));\n+            if (options == null) throw new ArgumentNullException(nameof(options));\n+\n+            var visitor = new Visitor(writer,\n+                                      options.IncludeLineColumn, options.IncludeRange,\n+                                      options.LocationMembersPlacement);\n+\n+            visitor.Visit(node);\n+        }\n+\n+        sealed class Visitor : AstVisitor\n+        {\n+            readonly JsonWriter _writer;\n+            readonly ObservableStack<INode> _stack;\n+\n+            public Visitor(JsonWriter writer,\n+                           bool includeLineColumn, bool includeRange,\n+                           LocationMembersPlacement locationMembersPlacement)\n+            {\n+                _writer = writer ?? throw new ArgumentNullException(nameof(writer));\n+                _stack = new ObservableStack<INode>();\n+\n+                if (includeLineColumn || includeRange)\n+                {\n+                    _stack.Pushed += node =>\n+                    {\n+                        writer.Object();\n+                        if (locationMembersPlacement == LocationMembersPlacement.Start)\n+                            WriteLocationInfo(node);\n+                        Member(\"type\", node.Type.ToString());","path":"src/Esprima/Utils/AstJson.cs","position":126,"original_position":126,"commit_id":"1955cab93bcf40a31151b4a903e85650a04d2cea","original_commit_id":"1955cab93bcf40a31151b4a903e85650a04d2cea","user":{"login":"atifaziz","id":20511,"node_id":"MDQ6VXNlcjIwNTEx","avatar_url":"https://avatars2.githubusercontent.com/u/20511?v=4","gravatar_id":"","url":"https://api.github.com/users/atifaziz","html_url":"https://github.com/atifaziz","followers_url":"https://api.github.com/users/atifaziz/followers","following_url":"https://api.github.com/users/atifaziz/following{/other_user}","gists_url":"https://api.github.com/users/atifaziz/gists{/gist_id}","starred_url":"https://api.github.com/users/atifaziz/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/atifaziz/subscriptions","organizations_url":"https://api.github.com/users/atifaziz/orgs","repos_url":"https://api.github.com/users/atifaziz/repos","events_url":"https://api.github.com/users/atifaziz/events{/privacy}","received_events_url":"https://api.github.com/users/atifaziz/received_events","type":"User","site_admin":false},"body":"Good point and I can't remember so I did a quick test in C# interactive:\r\n\r\n```\r\nMicrosoft (R) Visual C# Interactive Compiler version 2.10.0.0\r\nCopyright (C) Microsoft Corporation. All rights reserved.\r\n\r\nType \"#help\" for more information.\r\n> #r \"A:\\esprima-dotnet\\src\\Esprima\\bin\\Debug\\net45\\Esprima.dll\"\r\n> using Esprima.Ast;\r\n> var s1 = Enum.Parse(typeof(Nodes), \"ArrayExpression\").ToString();\r\n> var s2 = Nodes.ArrayExpression.ToString();\r\n> Console.WriteLine(object.ReferenceEquals(s1, s2));\r\nTrue\r\n```\r\n\r\nTurns out, the string references are the same. ","created_at":"2019-01-03T14:17:05Z","updated_at":"2019-01-03T14:17:05Z","html_url":"https://github.com/sebastienros/esprima-dotnet/pull/61#discussion_r245011874","pull_request_url":"https://api.github.com/repos/sebastienros/esprima-dotnet/pulls/61","author_association":"CONTRIBUTOR","_links":{"self":{"href":"https://api.github.com/repos/sebastienros/esprima-dotnet/pulls/comments/245011874"},"html":{"href":"https://github.com/sebastienros/esprima-dotnet/pull/61#discussion_r245011874"},"pull_request":{"href":"https://api.github.com/repos/sebastienros/esprima-dotnet/pulls/61"}},"in_reply_to_id":244952638},"pull_request":{"url":"https://api.github.com/repos/sebastienros/esprima-dotnet/pulls/61","id":241944344,"node_id":"MDExOlB1bGxSZXF1ZXN0MjQxOTQ0MzQ0","html_url":"https://github.com/sebastienros/esprima-dotnet/pull/61","diff_url":"https://github.com/sebastienros/esprima-dotnet/pull/61.diff","patch_url":"https://github.com/sebastienros/esprima-dotnet/pull/61.patch","issue_url":"https://api.github.com/repos/sebastienros/esprima-dotnet/issues/61","number":61,"state":"open","locked":false,"title":"Add AST JSON writer, removing Json.NET dependency","user":{"login":"atifaziz","id":20511,"node_id":"MDQ6VXNlcjIwNTEx","avatar_url":"https://avatars2.githubusercontent.com/u/20511?v=4","gravatar_id":"","url":"https://api.github.com/users/atifaziz","html_url":"https://github.com/atifaziz","followers_url":"https://api.github.com/users/atifaziz/followers","following_url":"https://api.github.com/users/atifaziz/following{/other_user}","gists_url":"https://api.github.com/users/atifaziz/gists{/gist_id}","starred_url":"https://api.github.com/users/atifaziz/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/atifaziz/subscriptions","organizations_url":"https://api.github.com/users/atifaziz/orgs","repos_url":"https://api.github.com/users/atifaziz/repos","events_url":"https://api.github.com/users/atifaziz/events{/privacy}","received_events_url":"https://api.github.com/users/atifaziz/received_events","type":"User","site_admin":false},"body":"This PR addresses issue #3.\r\n\r\nAll tests are passing. ✔️ \r\n\r\n## Implementation Notes for Review\r\n\r\nThere's a new type called `AstJson`  that's responsible for writing out the [AST tree](https://esprima.readthedocs.io/en/latest/syntax-tree-format.html) in JSON format. Internally, it has an implementation of `AstVisitor` that's the real workhorse so `AstJson` is the public API surface. Most of the methods are implemented as extensions for `INode`:\r\n\r\n- `ToJsonString` returns the JSON text as a string\r\n- `WriteJson` writes the JSON to a `TextWriter` or `JsonWriter`\r\n\r\n`JsonWriter` is an abstract base class that models the emitted JSON so technically one doesn't even have to emit JSON! `JsonTextWriter` is a `JsonWriter` implementation that writes to a `TextWriter` and can pretty-print given a string (which should only contain horizontal whitespace though this is not validated) for indentation. `JsonTextWriter` doesn't have to be public if we want to keep the public API as small as necessary for 1.0 so let me know if you want me to change that.\r\n\r\nUsage is as simple as:\r\n\r\n```c#\r\nvar parser = new JavaScriptParser(source);\r\nvar program = parser.ParseProgram();\r\n\r\nprogram.WriteJson(Console.Out);\r\nConsole.WriteLine();\r\n\r\nvar json = program.ToJsonString();\r\n\r\nvar prettyJson = program.ToJsonString(indent: \"  \");\r\n```\r\n\r\n\r\nThe JSON-writing methods of `AstJson` accept an `Options` object that determine the following:\r\n\r\n- Whether node line and column information is emitted (`IncludeLineColumn`)\r\n- Whether node index-based range information is emitted (`IncludeRange`)\r\n- Where to place the location-related members (`LocationMembersPlacement`)\r\n\r\n`LocationMembersPlacement` determines whether the location members are placed at the start (`Start`) or the end (`End`) of the node. Suppose a literal of 42 in the tree, then `Start` would mean that `range` and `loc` members appear before any other node information:\r\n\r\n```json\r\n{\r\n    \"range\": [\r\n        11,\r\n        13\r\n    ],\r\n    \"loc\": {\r\n        \"start\": {\r\n            \"line\": 1,\r\n            \"column\": 11\r\n        },\r\n        \"end\": {\r\n            \"line\": 1,\r\n            \"column\": 13\r\n        }\r\n    },\r\n    \"type\": \"Literal\",\r\n    \"value\": 42,\r\n    \"raw\": \"42\",\r\n}\r\n```\r\n\r\nand `End` would mean that `range` and `loc` members appear after all other node information:\r\n\r\n```json\r\n{\r\n    \"type\": \"Literal\",\r\n    \"value\": 42,\r\n    \"raw\": \"42\",\r\n    \"range\": [\r\n        11,\r\n        13\r\n    ],\r\n    \"loc\": {\r\n        \"start\": {\r\n            \"line\": 1,\r\n            \"column\": 11\r\n        },\r\n        \"end\": {\r\n            \"line\": 1,\r\n            \"column\": 13\r\n        }\r\n    }\r\n}\r\n```\r\n\r\nWhy did I do this? I found the C# implementation behaved like `LocationMembersPlacement.Start` whereas the JavaScript version behaved like `LocationMembersPlacement.End`. The unit tests don't seem to care about the ordering but it helps when you're looking to compare the tree JSON outputs (e.g. using a text diff program) between the two implementations. The default value for  `LocationMembersPlacement` is `End` so the default behaviour naturally imitates the JavaScript version for the least surprise. We can debate whether this is an overkill or a fare option to let the user control.\r\n\r\nFinally, the `INode.Range` was changed from being always an array of two integers:\r\n\r\n```c#\r\npublic interface INode\r\n{\r\n    Nodes Type { get; }\r\n    int[] Range { get; set; }\r\n    Location Location { get; set; }\r\n}\r\n```\r\n\r\nto a new `Range` structure:\r\n\r\n```c#\r\npublic interface INode\r\n{\r\n    Nodes Type { get; }\r\n    int[] Range { get; set; }\r\n    Location Location { get; set; }\r\n}\r\n\r\npublic struct Range\r\n{\r\n    public readonly int Start;\r\n    public readonly int End;\r\n\r\n    public Range(int start, int end)\r\n    {\r\n        Start = start;\r\n        End = end;\r\n    }\r\n}\r\n```\r\n\r\nBesides being strong-typed, this reduces heap allocations in a big way. My assumption here was that `INode.Range` was typed as `int[]` to have Json.NET emit it as a JSON array. With `AstJson`, there is no longer a need to keep 1:1 parity between the JSON format and the in-memory structures.\r\n\r\nThe dependency on Json.NET is done in a separate commit (1955cab93bcf40a31151b4a903e85650a04d2cea) in this PR in the hope that it makes it easier to review and revert should I have completely failed at this. 🙃 ","created_at":"2019-01-03T09:41:00Z","updated_at":"2019-01-03T14:17:05Z","closed_at":null,"merged_at":null,"merge_commit_sha":"ce6720d2966854b80ed2ca1603342248c5367bc0","assignee":null,"assignees":[],"requested_reviewers":[],"requested_teams":[],"labels":[],"milestone":null,"commits_url":"https://api.github.com/repos/sebastienros/esprima-dotnet/pulls/61/commits","review_comments_url":"https://api.github.com/repos/sebastienros/esprima-dotnet/pulls/61/comments","review_comment_url":"https://api.github.com/repos/sebastienros/esprima-dotnet/pulls/comments{/number}","comments_url":"https://api.github.com/repos/sebastienros/esprima-dotnet/issues/61/comments","statuses_url":"https://api.github.com/repos/sebastienros/esprima-dotnet/statuses/1955cab93bcf40a31151b4a903e85650a04d2cea","head":{"label":"atifaziz:x-json-net","ref":"x-json-net","sha":"1955cab93bcf40a31151b4a903e85650a04d2cea","user":{"login":"atifaziz","id":20511,"node_id":"MDQ6VXNlcjIwNTEx","avatar_url":"https://avatars2.githubusercontent.com/u/20511?v=4","gravatar_id":"","url":"https://api.github.com/users/atifaziz","html_url":"https://github.com/atifaziz","followers_url":"https://api.github.com/users/atifaziz/followers","following_url":"https://api.github.com/users/atifaziz/following{/other_user}","gists_url":"https://api.github.com/users/atifaziz/gists{/gist_id}","starred_url":"https://api.github.com/users/atifaziz/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/atifaziz/subscriptions","organizations_url":"https://api.github.com/users/atifaziz/orgs","repos_url":"https://api.github.com/users/atifaziz/repos","events_url":"https://api.github.com/users/atifaziz/events{/privacy}","received_events_url":"https://api.github.com/users/atifaziz/received_events","type":"User","site_admin":false},"repo":{"id":161825024,"node_id":"MDEwOlJlcG9zaXRvcnkxNjE4MjUwMjQ=","name":"esprima-dotnet","full_name":"atifaziz/esprima-dotnet","private":false,"owner":{"login":"atifaziz","id":20511,"node_id":"MDQ6VXNlcjIwNTEx","avatar_url":"https://avatars2.githubusercontent.com/u/20511?v=4","gravatar_id":"","url":"https://api.github.com/users/atifaziz","html_url":"https://github.com/atifaziz","followers_url":"https://api.github.com/users/atifaziz/followers","following_url":"https://api.github.com/users/atifaziz/following{/other_user}","gists_url":"https://api.github.com/users/atifaziz/gists{/gist_id}","starred_url":"https://api.github.com/users/atifaziz/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/atifaziz/subscriptions","organizations_url":"https://api.github.com/users/atifaziz/orgs","repos_url":"https://api.github.com/users/atifaziz/repos","events_url":"https://api.github.com/users/atifaziz/events{/privacy}","received_events_url":"https://api.github.com/users/atifaziz/received_events","type":"User","site_admin":false},"html_url":"https://github.com/atifaziz/esprima-dotnet","description":"Esprima .NET (BSD license) is a .NET port of the esprima.org project. It is a standard-compliant ECMAScript parser (also popularly known as JavaScript).","fork":true,"url":"https://api.github.com/repos/atifaziz/esprima-dotnet","forks_url":"https://api.github.com/repos/atifaziz/esprima-dotnet/forks","keys_url":"https://api.github.com/repos/atifaziz/esprima-dotnet/keys{/key_id}","collaborators_url":"https://api.github.com/repos/atifaziz/esprima-dotnet/collaborators{/collaborator}","teams_url":"https://api.github.com/repos/atifaziz/esprima-dotnet/teams","hooks_url":"https://api.github.com/repos/atifaziz/esprima-dotnet/hooks","issue_events_url":"https://api.github.com/repos/atifaziz/esprima-dotnet/issues/events{/number}","events_url":"https://api.github.com/repos/atifaziz/esprima-dotnet/events","assignees_url":"https://api.github.com/repos/atifaziz/esprima-dotnet/assignees{/user}","branches_url":"https://api.github.com/repos/atifaziz/esprima-dotnet/branches{/branch}","tags_url":"https://api.github.com/repos/atifaziz/esprima-dotnet/tags","blobs_url":"https://api.github.com/repos/atifaziz/esprima-dotnet/git/blobs{/sha}","git_tags_url":"https://api.github.com/repos/atifaziz/esprima-dotnet/git/tags{/sha}","git_refs_url":"https://api.github.com/repos/atifaziz/esprima-dotnet/git/refs{/sha}","trees_url":"https://api.github.com/repos/atifaziz/esprima-dotnet/git/trees{/sha}","statuses_url":"https://api.github.com/repos/atifaziz/esprima-dotnet/statuses/{sha}","languages_url":"https://api.github.com/repos/atifaziz/esprima-dotnet/languages","stargazers_url":"https://api.github.com/repos/atifaziz/esprima-dotnet/stargazers","contributors_url":"https://api.github.com/repos/atifaziz/esprima-dotnet/contributors","subscribers_url":"https://api.github.com/repos/atifaziz/esprima-dotnet/subscribers","subscription_url":"https://api.github.com/repos/atifaziz/esprima-dotnet/subscription","commits_url":"https://api.github.com/repos/atifaziz/esprima-dotnet/commits{/sha}","git_commits_url":"https://api.github.com/repos/atifaziz/esprima-dotnet/git/commits{/sha}","comments_url":"https://api.github.com/repos/atifaziz/esprima-dotnet/comments{/number}","issue_comment_url":"https://api.github.com/repos/atifaziz/esprima-dotnet/issues/comments{/number}","contents_url":"https://api.github.com/repos/atifaziz/esprima-dotnet/contents/{+path}","compare_url":"https://api.github.com/repos/atifaziz/esprima-dotnet/compare/{base}...{head}","merges_url":"https://api.github.com/repos/atifaziz/esprima-dotnet/merges","archive_url":"https://api.github.com/repos/atifaziz/esprima-dotnet/{archive_format}{/ref}","downloads_url":"https://api.github.com/repos/atifaziz/esprima-dotnet/downloads","issues_url":"https://api.github.com/repos/atifaziz/esprima-dotnet/issues{/number}","pulls_url":"https://api.github.com/repos/atifaziz/esprima-dotnet/pulls{/number}","milestones_url":"https://api.github.com/repos/atifaziz/esprima-dotnet/milestones{/number}","notifications_url":"https://api.github.com/repos/atifaziz/esprima-dotnet/notifications{?since,all,participating}","labels_url":"https://api.github.com/repos/atifaziz/esprima-dotnet/labels{/name}","releases_url":"https://api.github.com/repos/atifaziz/esprima-dotnet/releases{/id}","deployments_url":"https://api.github.com/repos/atifaziz/esprima-dotnet/deployments","created_at":"2018-12-14T18:25:53Z","updated_at":"2019-01-02T23:33:06Z","pushed_at":"2019-01-03T09:50:56Z","git_url":"git://github.com/atifaziz/esprima-dotnet.git","ssh_url":"git@github.com:atifaziz/esprima-dotnet.git","clone_url":"https://github.com/atifaziz/esprima-dotnet.git","svn_url":"https://github.com/atifaziz/esprima-dotnet","homepage":"","size":8270,"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":"other","name":"Other","spdx_id":"NOASSERTION","url":null,"node_id":"MDc6TGljZW5zZTA="},"forks":0,"open_issues":0,"watchers":0,"default_branch":"dev"}},"base":{"label":"sebastienros:dev","ref":"dev","sha":"6530a1cc686b6a3bfd8b4b7b588d5777816991dc","user":{"login":"sebastienros","id":1165805,"node_id":"MDQ6VXNlcjExNjU4MDU=","avatar_url":"https://avatars0.githubusercontent.com/u/1165805?v=4","gravatar_id":"","url":"https://api.github.com/users/sebastienros","html_url":"https://github.com/sebastienros","followers_url":"https://api.github.com/users/sebastienros/followers","following_url":"https://api.github.com/users/sebastienros/following{/other_user}","gists_url":"https://api.github.com/users/sebastienros/gists{/gist_id}","starred_url":"https://api.github.com/users/sebastienros/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/sebastienros/subscriptions","organizations_url":"https://api.github.com/users/sebastienros/orgs","repos_url":"https://api.github.com/users/sebastienros/repos","events_url":"https://api.github.com/users/sebastienros/events{/privacy}","received_events_url":"https://api.github.com/users/sebastienros/received_events","type":"User","site_admin":false},"repo":{"id":69628756,"node_id":"MDEwOlJlcG9zaXRvcnk2OTYyODc1Ng==","name":"esprima-dotnet","full_name":"sebastienros/esprima-dotnet","private":false,"owner":{"login":"sebastienros","id":1165805,"node_id":"MDQ6VXNlcjExNjU4MDU=","avatar_url":"https://avatars0.githubusercontent.com/u/1165805?v=4","gravatar_id":"","url":"https://api.github.com/users/sebastienros","html_url":"https://github.com/sebastienros","followers_url":"https://api.github.com/users/sebastienros/followers","following_url":"https://api.github.com/users/sebastienros/following{/other_user}","gists_url":"https://api.github.com/users/sebastienros/gists{/gist_id}","starred_url":"https://api.github.com/users/sebastienros/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/sebastienros/subscriptions","organizations_url":"https://api.github.com/users/sebastienros/orgs","repos_url":"https://api.github.com/users/sebastienros/repos","events_url":"https://api.github.com/users/sebastienros/events{/privacy}","received_events_url":"https://api.github.com/users/sebastienros/received_events","type":"User","site_admin":false},"html_url":"https://github.com/sebastienros/esprima-dotnet","description":"Esprima .NET (BSD license) is a .NET port of the esprima.org project. It is a standard-compliant ECMAScript parser (also popularly known as JavaScript).","fork":false,"url":"https://api.github.com/repos/sebastienros/esprima-dotnet","forks_url":"https://api.github.com/repos/sebastienros/esprima-dotnet/forks","keys_url":"https://api.github.com/repos/sebastienros/esprima-dotnet/keys{/key_id}","collaborators_url":"https://api.github.com/repos/sebastienros/esprima-dotnet/collaborators{/collaborator}","teams_url":"https://api.github.com/repos/sebastienros/esprima-dotnet/teams","hooks_url":"https://api.github.com/repos/sebastienros/esprima-dotnet/hooks","issue_events_url":"https://api.github.com/repos/sebastienros/esprima-dotnet/issues/events{/number}","events_url":"https://api.github.com/repos/sebastienros/esprima-dotnet/events","assignees_url":"https://api.github.com/repos/sebastienros/esprima-dotnet/assignees{/user}","branches_url":"https://api.github.com/repos/sebastienros/esprima-dotnet/branches{/branch}","tags_url":"https://api.github.com/repos/sebastienros/esprima-dotnet/tags","blobs_url":"https://api.github.com/repos/sebastienros/esprima-dotnet/git/blobs{/sha}","git_tags_url":"https://api.github.com/repos/sebastienros/esprima-dotnet/git/tags{/sha}","git_refs_url":"https://api.github.com/repos/sebastienros/esprima-dotnet/git/refs{/sha}","trees_url":"https://api.github.com/repos/sebastienros/esprima-dotnet/git/trees{/sha}","statuses_url":"https://api.github.com/repos/sebastienros/esprima-dotnet/statuses/{sha}","languages_url":"https://api.github.com/repos/sebastienros/esprima-dotnet/languages","stargazers_url":"https://api.github.com/repos/sebastienros/esprima-dotnet/stargazers","contributors_url":"https://api.github.com/repos/sebastienros/esprima-dotnet/contributors","subscribers_url":"https://api.github.com/repos/sebastienros/esprima-dotnet/subscribers","subscription_url":"https://api.github.com/repos/sebastienros/esprima-dotnet/subscription","commits_url":"https://api.github.com/repos/sebastienros/esprima-dotnet/commits{/sha}","git_commits_url":"https://api.github.com/repos/sebastienros/esprima-dotnet/git/commits{/sha}","comments_url":"https://api.github.com/repos/sebastienros/esprima-dotnet/comments{/number}","issue_comment_url":"https://api.github.com/repos/sebastienros/esprima-dotnet/issues/comments{/number}","contents_url":"https://api.github.com/repos/sebastienros/esprima-dotnet/contents/{+path}","compare_url":"https://api.github.com/repos/sebastienros/esprima-dotnet/compare/{base}...{head}","merges_url":"https://api.github.com/repos/sebastienros/esprima-dotnet/merges","archive_url":"https://api.github.com/repos/sebastienros/esprima-dotnet/{archive_format}{/ref}","downloads_url":"https://api.github.com/repos/sebastienros/esprima-dotnet/downloads","issues_url":"https://api.github.com/repos/sebastienros/esprima-dotnet/issues{/number}","pulls_url":"https://api.github.com/repos/sebastienros/esprima-dotnet/pulls{/number}","milestones_url":"https://api.github.com/repos/sebastienros/esprima-dotnet/milestones{/number}","notifications_url":"https://api.github.com/repos/sebastienros/esprima-dotnet/notifications{?since,all,participating}","labels_url":"https://api.github.com/repos/sebastienros/esprima-dotnet/labels{/name}","releases_url":"https://api.github.com/repos/sebastienros/esprima-dotnet/releases{/id}","deployments_url":"https://api.github.com/repos/sebastienros/esprima-dotnet/deployments","created_at":"2016-09-30T03:04:06Z","updated_at":"2019-01-02T23:22:38Z","pushed_at":"2019-01-03T09:58:43Z","git_url":"git://github.com/sebastienros/esprima-dotnet.git","ssh_url":"git@github.com:sebastienros/esprima-dotnet.git","clone_url":"https://github.com/sebastienros/esprima-dotnet.git","svn_url":"https://github.com/sebastienros/esprima-dotnet","homepage":"","size":8257,"stargazers_count":119,"watchers_count":119,"language":"C#","has_issues":true,"has_projects":true,"has_downloads":true,"has_wiki":true,"has_pages":false,"forks_count":21,"mirror_url":null,"archived":false,"open_issues_count":13,"license":{"key":"other","name":"Other","spdx_id":"NOASSERTION","url":null,"node_id":"MDc6TGljZW5zZTA="},"forks":21,"open_issues":13,"watchers":119,"default_branch":"dev"}},"_links":{"self":{"href":"https://api.github.com/repos/sebastienros/esprima-dotnet/pulls/61"},"html":{"href":"https://github.com/sebastienros/esprima-dotnet/pull/61"},"issue":{"href":"https://api.github.com/repos/sebastienros/esprima-dotnet/issues/61"},"comments":{"href":"https://api.github.com/repos/sebastienros/esprima-dotnet/issues/61/comments"},"review_comments":{"href":"https://api.github.com/repos/sebastienros/esprima-dotnet/pulls/61/comments"},"review_comment":{"href":"https://api.github.com/repos/sebastienros/esprima-dotnet/pulls/comments{/number}"},"commits":{"href":"https://api.github.com/repos/sebastienros/esprima-dotnet/pulls/61/commits"},"statuses":{"href":"https://api.github.com/repos/sebastienros/esprima-dotnet/statuses/1955cab93bcf40a31151b4a903e85650a04d2cea"}},"author_association":"CONTRIBUTOR"}}
{"actor":{"display_login":"atifaziz"}}