{"action":"created","comment":{"url":"https://api.github.com/repos/Microsoft/TypeScript/pulls/comments/24859671","id":24859671,"diff_hunk":"@@ -0,0 +1,1646 @@\n+/// <reference path=\"..\\compiler\\commandLineParser.ts\" />\r\n+/// <reference path=\"..\\services\\services.ts\" />\r\n+/// <reference path=\"node.d.ts\" />\r\n+\r\n+module ts.server {\r\n+    export interface Logger {\r\n+        close(): void;\r\n+        perftrc(s: string): void;\r\n+        info(s: string): void;\r\n+        startGroup(): void;\r\n+        endGroup(): void;\r\n+        msg(s: string, type?: string): void;\r\n+    }\r\n+\r\n+    var lineCollectionCapacity = 4;\r\n+\r\n+    class ScriptInfo {\r\n+        svc: ScriptVersionCache;\r\n+        children: ScriptInfo[] = [];     // files referenced by this file\r\n+\r\n+        defaultProject: Project;      // project to use by default for file\r\n+\r\n+        fileWatcher: FileWatcher;\r\n+\r\n+        constructor(private host: ServerHost, public fileName: string, public content: string, public isOpen = false) {\r\n+            this.svc = ScriptVersionCache.fromString(content);\r\n+        }\r\n+\r\n+        close() {\r\n+            this.isOpen = false;\r\n+        }\r\n+\r\n+        addChild(childInfo: ScriptInfo) {\r\n+            this.children.push(childInfo);\r\n+        }\r\n+\r\n+        snap() {\r\n+            return this.svc.getSnapshot();\r\n+        }\r\n+\r\n+        getText() {\r\n+            var snap = this.snap();\r\n+            return snap.getText(0, snap.getLength());\r\n+        }\r\n+\r\n+        getLineInfo(line: number) {\r\n+            var snap = this.snap();\r\n+            return snap.index.lineNumberToInfo(line);\r\n+        }\r\n+\r\n+        editContent(start: number, end: number, newText: string): void {\r\n+            this.svc.edit(start, end - start, newText);\r\n+        }\r\n+\r\n+        getTextChangeRangeBetweenVersions(startVersion: number, endVersion: number): ts.TextChangeRange {\r\n+            return this.svc.getTextChangesBetweenVersions(startVersion, endVersion);\r\n+        }\r\n+\r\n+        getChangeRange(oldSnapshot: ts.IScriptSnapshot): ts.TextChangeRange {\r\n+            return this.snap().getChangeRange(oldSnapshot);\r\n+        }\r\n+    }\r\n+\r\n+    class LSHost implements ts.LanguageServiceHost {\r\n+        ls: ts.LanguageService = null;\r\n+        compilationSettings: ts.CompilerOptions;\r\n+        filenameToScript: ts.Map<ScriptInfo> = {};\r\n+\r\n+        constructor(public host: ServerHost, public project: Project) {\r\n+        }\r\n+\r\n+        getDefaultLibFileName() {\r\n+            var nodeModuleBinDir = ts.getDirectoryPath(ts.normalizePath(this.host.getExecutingFilePath()));\r\n+            return ts.combinePaths(nodeModuleBinDir, ts.getDefaultLibFileName(this.compilationSettings));\r\n+        }\r\n+\r\n+        getScriptSnapshot(filename: string): ts.IScriptSnapshot {\r\n+            var scriptInfo = this.getScriptInfo(filename);\r\n+            if (scriptInfo) {\r\n+                return scriptInfo.snap();\r\n+            }\r\n+        }\r\n+\r\n+        setCompilationSettings(opt: ts.CompilerOptions) {\r\n+            this.compilationSettings = opt;\r\n+        }\r\n+\r\n+        lineAffectsRefs(filename: string, line: number) {\r\n+            var info = this.getScriptInfo(filename);\r\n+            var lineInfo = info.getLineInfo(line);\r\n+            if (lineInfo && lineInfo.text) {\r\n+                var regex = /reference|import|\\/\\*|\\*\\//;\r\n+                return regex.test(lineInfo.text);\r\n+            }\r\n+        }\r\n+\r\n+        getCompilationSettings() {\r\n+            // change this to return active project settings for file\r\n+            return this.compilationSettings;\r\n+        }\r\n+\r\n+        getScriptFileNames() {\r\n+            var filenames: string[] = [];\r\n+            for (var filename in this.filenameToScript) {\r\n+                if (this.filenameToScript[filename] && this.filenameToScript[filename].isOpen) {\r\n+                    filenames.push(filename);\r\n+                }\r\n+            }\r\n+            return filenames;\r\n+        }\r\n+\r\n+        getScriptVersion(filename: string) {\r\n+            return this.getScriptInfo(filename).svc.latestVersion().toString();\r\n+        }\r\n+\r\n+        getCurrentDirectory(): string {\r\n+            return \"\";\r\n+        }\r\n+\r\n+        getScriptIsOpen(filename: string) {\r\n+            return this.getScriptInfo(filename).isOpen;\r\n+        }\r\n+\r\n+        removeReferencedFile(info: ScriptInfo) {\r\n+            if (!info.isOpen) {\r\n+                this.filenameToScript[info.fileName] = undefined;\r\n+            }\r\n+        }\r\n+\r\n+        getScriptInfo(filename: string): ScriptInfo {\r\n+            var scriptInfo = ts.lookUp(this.filenameToScript, filename);\r\n+            if (!scriptInfo) {\r\n+                scriptInfo = this.project.openReferencedFile(filename);\r\n+                if (scriptInfo) {\r\n+                    this.filenameToScript[scriptInfo.fileName] = scriptInfo;\r\n+                }\r\n+            }\r\n+            else {\r\n+            }\r\n+            return scriptInfo;\r\n+        }\r\n+\r\n+        addRoot(info: ScriptInfo) {\r\n+            var scriptInfo = ts.lookUp(this.filenameToScript, info.fileName);\r\n+            if (!scriptInfo) {\r\n+                this.filenameToScript[info.fileName] = info;\r\n+                return info;\r\n+            }\r\n+        }\r\n+\r\n+        saveTo(filename: string, tmpfilename: string) {\r\n+            var script = this.getScriptInfo(filename);\r\n+            if (script) {\r\n+                var snap = script.snap();\r\n+                this.host.writeFile(tmpfilename, snap.getText(0, snap.getLength()));\r\n+            }\r\n+        }\r\n+\r\n+        reloadScript(filename: string, tmpfilename: string, cb: () => any) {\r\n+            var script = this.getScriptInfo(filename);\r\n+            if (script) {\r\n+                script.svc.reloadFromFile(tmpfilename, cb);\r\n+            }\r\n+        }\r\n+\r\n+        editScript(filename: string, start: number, end: number, newText: string) {\r\n+            var script = this.getScriptInfo(filename);\r\n+            if (script) {\r\n+                script.editContent(start, end, newText);\r\n+                return;\r\n+            }\r\n+\r\n+            throw new Error(\"No script with name '\" + filename + \"'\");\r\n+        }\r\n+\r\n+        resolvePath(path: string): string {\r\n+            var start = new Date().getTime();\r\n+            var result = this.host.resolvePath(path);\r\n+            return result;\r\n+        }\r\n+\r\n+        fileExists(path: string): boolean {\r\n+            var start = new Date().getTime();\r\n+            var result = this.host.fileExists(path);\r\n+            return result;\r\n+        }\r\n+\r\n+        directoryExists(path: string): boolean {\r\n+            return this.host.directoryExists(path);\r\n+        }\r\n+\r\n+        /**\r\n+         *  @param line 1 based index\r\n+         */\r\n+        lineToTextSpan(filename: string, line: number): ts.TextSpan {\r\n+            var script: ScriptInfo = this.filenameToScript[filename];\r\n+            var index = script.snap().index;\r\n+\r\n+            var lineInfo = index.lineNumberToInfo(line + 1);\r\n+            var len: number;\r\n+            if (lineInfo.leaf) {\r\n+                len = lineInfo.leaf.text.length;\r\n+            }\r\n+            else {\r\n+                var nextLineInfo = index.lineNumberToInfo(line + 2);\r\n+                len = nextLineInfo.col - lineInfo.col;\r\n+            }\r\n+            return ts.createTextSpan(lineInfo.col, len);\r\n+        }\r\n+\r\n+        /**\r\n+         * @param line 1 based index\r\n+         * @param col 1 based index\r\n+         */\r\n+        lineColToPosition(filename: string, line: number, col: number): number {\r\n+            var script: ScriptInfo = this.filenameToScript[filename];\r\n+            var index = script.snap().index;\r\n+\r\n+            var lineInfo = index.lineNumberToInfo(line);\r\n+            // TODO: assert this column is actually on the line\r\n+            return (lineInfo.col + col - 1);\r\n+        }\r\n+\r\n+        /**\r\n+         * @param line 1-based index\r\n+         * @param col 1-based index\r\n+         */\r\n+        positionToLineCol(filename: string, position: number): ILineInfo {\r\n+            var script: ScriptInfo = this.filenameToScript[filename];\r\n+            var index = script.snap().index;\r\n+            var lineCol = index.charOffsetToLineNumberAndPos(position);\r\n+            return { line: lineCol.line, col: lineCol.col + 1 };\r\n+        }\r\n+    }\r\n+\r\n+    // assumes normalized paths\r\n+    function getAbsolutePath(filename: string, directory: string) {\r\n+        var rootLength = ts.getRootLength(filename);\r\n+        if (rootLength > 0) {\r\n+            return filename;\r\n+        }\r\n+        else {\r\n+            var splitFilename = filename.split('/');\r\n+            var splitDir = directory.split('/');\r\n+            var i = 0;\r\n+            var dirTail = 0;\r\n+            var sflen = splitFilename.length;\r\n+            while ((i < sflen) && (splitFilename[i].charAt(0) == '.')) {\r\n+                var dots = splitFilename[i];\r\n+                if (dots == '..') {\r\n+                    dirTail++;\r\n+                }\r\n+                else if (dots != '.') {\r\n+                    return undefined;\r\n+                }\r\n+                i++;\r\n+            }\r\n+            return splitDir.slice(0, splitDir.length - dirTail).concat(splitFilename.slice(i)).join('/');\r\n+        }\r\n+    }\r\n+\r\n+    interface ProjectOptions {\r\n+        // these fields can be present in the project file\r\n+        files?: string[];\r\n+        formatCodeOptions?: ts.FormatCodeOptions;\r\n+        compilerOptions?: ts.CompilerOptions;\r\n+    }\r\n+\r\n+    export class Project {\r\n+        compilerService: CompilerService;\r\n+        projectOptions: ProjectOptions;\r\n+        projectFilename: string;\r\n+        program: ts.Program;\r\n+        filenameToSourceFile: ts.Map<ts.SourceFile> = {};\r\n+        updateGraphSeq = 0;\r\n+\r\n+        constructor(public projectService: ProjectService) {\r\n+            this.compilerService = new CompilerService(this);\r\n+        }\r\n+\r\n+        openReferencedFile(filename: string) {\r\n+            return this.projectService.openFile(filename, false);\r\n+        }\r\n+\r\n+        getSourceFile(info: ScriptInfo) {\r\n+            return this.filenameToSourceFile[info.fileName];\r\n+        }\r\n+\r\n+        getSourceFileFromName(filename: string) {\r\n+            var info = this.projectService.getScriptInfo(filename);\r\n+            if (info) {\r\n+                return this.getSourceFile(info);\r\n+            }\r\n+        }\r\n+\r\n+        removeReferencedFile(info: ScriptInfo) {\r\n+            this.compilerService.host.removeReferencedFile(info);\r\n+            this.updateGraph();\r\n+        }\r\n+\r\n+        updateFileMap() {\r\n+            this.filenameToSourceFile = {};\r\n+            var sourceFiles = this.program.getSourceFiles();\r\n+            for (var i = 0, len = sourceFiles.length; i < len; i++) {\r\n+                var normFilename = ts.normalizePath(sourceFiles[i].fileName);\r\n+                this.filenameToSourceFile[normFilename] = sourceFiles[i];\r\n+            }\r\n+        }\r\n+\r\n+        finishGraph() {\r\n+            this.updateGraph();\r\n+            this.compilerService.languageService.getNavigateToItems(\".*\");\r\n+        }\r\n+\r\n+        updateGraph() {\r\n+            this.program = this.compilerService.languageService.getProgram();\r\n+            this.updateFileMap();\r\n+        }\r\n+\r\n+        isConfiguredProject() {\r\n+            return this.projectFilename;\r\n+        }\r\n+\r\n+        // add a root file to project\r\n+        addRoot(info: ScriptInfo) {\r\n+            info.defaultProject = this;\r\n+            return this.compilerService.host.addRoot(info);\r\n+        }\r\n+\r\n+        filesToString() {\r\n+            var strBuilder = \"\";\r\n+            ts.forEachValue(this.filenameToSourceFile,\r\n+                sourceFile => { strBuilder += sourceFile.fileName + \"\\n\"; });\r\n+            return strBuilder;\r\n+        }\r\n+\r\n+        setProjectOptions(projectOptions: ProjectOptions) {\r\n+            this.projectOptions = projectOptions;\r\n+            if (projectOptions.compilerOptions) {\r\n+                this.compilerService.setCompilerOptions(projectOptions.compilerOptions);\r\n+            }\r\n+            // TODO: format code options\r\n+        }\r\n+    }\r\n+\r\n+    interface ProjectOpenResult {\r\n+        success?: boolean;\r\n+        errorMsg?: string;\r\n+        project?: Project;\r\n+    }\r\n+\r\n+    function copyListRemovingItem<T>(item: T, list: T[]) {\r\n+        var copiedList: T[] = [];\r\n+        for (var i = 0, len = list.length; i < len; i++) {\r\n+            if (list[i] != item) {\r\n+                copiedList.push(list[i]);\r\n+            }\r\n+        }\r\n+        return copiedList;\r\n+    }\r\n+\r\n+    interface ProjectServiceEventHandler {\r\n+        (eventName: string, project: Project): void;\r\n+    }\r\n+\r\n+    export class ProjectService {\r\n+        filenameToScriptInfo: ts.Map<ScriptInfo> = {};\r\n+        // open, non-configured files in two lists\r\n+        openFileRoots: ScriptInfo[] = [];\r\n+        openFilesReferenced: ScriptInfo[] = [];\r\n+        // projects covering open files\r\n+        inferredProjects: Project[] = [];\r\n+\r\n+        constructor(public host: ServerHost, public psLogger: Logger, public eventHandler?: ProjectServiceEventHandler) {\r\n+            // ts.disableIncrementalParsing = true;\r\n+        }\r\n+\r\n+        watchedFileChanged(fileName: string) {\r\n+            var info = this.filenameToScriptInfo[fileName];\r\n+            if (!info) {\r\n+                this.psLogger.info(\"Error: got watch notification for unknown file: \" + fileName);\r\n+            }\r\n+\r\n+            if (!this.host.fileExists(fileName)) {\r\n+                // File was deleted\r\n+                this.fileDeletedInFilesystem(info);\r\n+            }\r\n+            else {\r\n+                if (info && (!info.isOpen)) {\r\n+                    info.svc.reloadFromFile(info.fileName);\r\n+                }\r\n+            }\r\n+        }\r\n+        \r\n+\r\n+        log(msg: string, type = \"Err\") {\r\n+            this.psLogger.msg(msg, type);\r\n+        }\r\n+\r\n+        closeLog() {\r\n+            this.psLogger.close();\r\n+        }\r\n+\r\n+        createInferredProject(root: ScriptInfo) {\r\n+            var iproj = new Project(this);\r\n+            iproj.addRoot(root);\r\n+            iproj.finishGraph();\r\n+            this.inferredProjects.push(iproj);\r\n+            return iproj;\r\n+        }\r\n+\r\n+        fileDeletedInFilesystem(info: ScriptInfo) {\r\n+            this.psLogger.info(info.fileName + \" deleted\");\r\n+            \r\n+            if (info.fileWatcher) {\r\n+                info.fileWatcher.close();\r\n+                info.fileWatcher = undefined;\r\n+            }\r\n+\r\n+            if (!info.isOpen) {\r\n+                this.filenameToScriptInfo[info.fileName] = undefined;\r\n+                var referencingProjects = this.findReferencingProjects(info);\r\n+                for (var i = 0, len = referencingProjects.length; i < len; i++) {\r\n+                    referencingProjects[i].removeReferencedFile(info);\r\n+                }\r\n+            }\r\n+            this.printProjects();\r\n+        }\r\n+\r\n+        addOpenFile(info: ScriptInfo) {\r\n+            this.findReferencingProjects(info);\r\n+            if (info.defaultProject) {\r\n+                this.openFilesReferenced.push(info);\r\n+            }\r\n+            else {\r\n+                // create new inferred project p with the newly opened file as root\r\n+                info.defaultProject = this.createInferredProject(info);\r\n+                var openFileRoots: ScriptInfo[] = [];\r\n+                // for each inferred project root r\r\n+                for (var i = 0, len = this.openFileRoots.length; i < len; i++) {\r\n+                    var r = this.openFileRoots[i];\r\n+                    // if r referenced by the new project\r\n+                    if (info.defaultProject.getSourceFile(r)) {\r\n+                        // remove project rooted at r\r\n+                        this.inferredProjects =\r\n+                        copyListRemovingItem(r.defaultProject, this.inferredProjects);\r\n+                        // put r in referenced open file list\r\n+                        this.openFilesReferenced.push(r);\r\n+                        // set default project of r to the new project \r\n+                        r.defaultProject = info.defaultProject;\r\n+                    }\r\n+                    else {\r\n+                        // otherwise, keep r as root of inferred project\r\n+                        openFileRoots.push(r);\r\n+                    }\r\n+                }\r\n+                this.openFileRoots = openFileRoots;\r\n+                this.openFileRoots.push(info);\r\n+            }\r\n+        }\r\n+\r\n+        closeOpenFile(info: ScriptInfo) {\r\n+            var openFileRoots: ScriptInfo[] = [];\r\n+            var removedProject: Project;\r\n+            for (var i = 0, len = this.openFileRoots.length; i < len; i++) {\r\n+                // if closed file is root of project\r\n+                if (info == this.openFileRoots[i]) {\r\n+                    // remove that project and remember it\r\n+                    removedProject = info.defaultProject;\r\n+                }\r\n+                else {\r\n+                    openFileRoots.push(this.openFileRoots[i]);\r\n+                }\r\n+            }\r\n+            this.openFileRoots = openFileRoots;\r\n+            if (removedProject) {\r\n+                // remove project from inferred projects list\r\n+                this.inferredProjects = copyListRemovingItem(removedProject, this.inferredProjects);\r","path":"src/server/editorServices.ts","position":478,"original_position":478,"commit_id":"cadd57c10fe8036661427c9bf4fa1c22c85658c3","original_commit_id":"cadd57c10fe8036661427c9bf4fa1c22c85658c3","user":{"login":"DanielRosenwasser","id":972891,"avatar_url":"https://avatars.githubusercontent.com/u/972891?v=3","gravatar_id":"","url":"https://api.github.com/users/DanielRosenwasser","html_url":"https://github.com/DanielRosenwasser","followers_url":"https://api.github.com/users/DanielRosenwasser/followers","following_url":"https://api.github.com/users/DanielRosenwasser/following{/other_user}","gists_url":"https://api.github.com/users/DanielRosenwasser/gists{/gist_id}","starred_url":"https://api.github.com/users/DanielRosenwasser/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/DanielRosenwasser/subscriptions","organizations_url":"https://api.github.com/users/DanielRosenwasser/orgs","repos_url":"https://api.github.com/users/DanielRosenwasser/repos","events_url":"https://api.github.com/users/DanielRosenwasser/events{/privacy}","received_events_url":"https://api.github.com/users/DanielRosenwasser/received_events","type":"User","site_admin":false},"body":"If this is going to be private, stop doing filters and just remove it in place.","created_at":"2015-02-17T22:12:14Z","updated_at":"2015-02-17T22:12:14Z","html_url":"https://github.com/Microsoft/TypeScript/pull/2041#discussion_r24859671","pull_request_url":"https://api.github.com/repos/Microsoft/TypeScript/pulls/2041","_links":{"self":{"href":"https://api.github.com/repos/Microsoft/TypeScript/pulls/comments/24859671"},"html":{"href":"https://github.com/Microsoft/TypeScript/pull/2041#discussion_r24859671"},"pull_request":{"href":"https://api.github.com/repos/Microsoft/TypeScript/pulls/2041"}}},"pull_request":{"url":"https://api.github.com/repos/Microsoft/TypeScript/pulls/2041","id":29349408,"html_url":"https://github.com/Microsoft/TypeScript/pull/2041","diff_url":"https://github.com/Microsoft/TypeScript/pull/2041.diff","patch_url":"https://github.com/Microsoft/TypeScript/pull/2041.patch","issue_url":"https://api.github.com/repos/Microsoft/TypeScript/issues/2041","number":2041,"state":"open","locked":false,"title":"TS Server","user":{"login":"mhegazy","id":8000722,"avatar_url":"https://avatars.githubusercontent.com/u/8000722?v=3","gravatar_id":"","url":"https://api.github.com/users/mhegazy","html_url":"https://github.com/mhegazy","followers_url":"https://api.github.com/users/mhegazy/followers","following_url":"https://api.github.com/users/mhegazy/following{/other_user}","gists_url":"https://api.github.com/users/mhegazy/gists{/gist_id}","starred_url":"https://api.github.com/users/mhegazy/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/mhegazy/subscriptions","organizations_url":"https://api.github.com/users/mhegazy/orgs","repos_url":"https://api.github.com/users/mhegazy/repos","events_url":"https://api.github.com/users/mhegazy/events{/privacy}","received_events_url":"https://api.github.com/users/mhegazy/received_events","type":"User","site_admin":false},"body":"The basic LanguageService interface puts some requirements on the \"host\", such as an implementation of a ScriptSnapshot system to support incremental parsing, managing contexts, monitoring files on disk, scheduling diagnostic queries, maintaining line map for line/column for positions for files, etc.. Every editor plugin is required to implement the expected host functionality, possibly in different languages. \r\n\r\nThis change exposes a new interface to the Services layer (ts server), through a JSON-based communication protocol. Behind the protocol, the server supports all the common host functionality,:\r\n- A ScriptSnapshot management system with support for diffing script snapshots to allow efficient incremental parsing. A client would send a stream of text changes, and the server will maintain an updated version of the text in memory that can then be used to drive LS requests.\r\n- A Project management service that allows for figuring project structure a la VS Virtual Projects, allowing the client to ignore resolving references, and maintaining project structure. The project management service also should supports different modes e.g. lose files, ts config, /// references, and imports. The client just informs the server about open files, and the server takes the responsibility of figuring out what files are interesting to this context. the client then asks for operations like completions, quick info, etc.. directly on the file.\r\n- Managing closed file state without requiring the client to monitor them. The server adds file watches to all files in a project, and triggers re computation for errors and updates context once a file has changed on disk. \r\n- Diagnostics update scheduling, the client does not need to trigger diagnostics update requests; the server sends events with errors whenever this is needed.\r\n- A line/column interface with no need to keep a line map for all files. the server does not request any positions in its calls.\r\n\r\nThe server is mainly available as an IO process that a client would create in a separate process and communicates with it over stdin/stdout.\r\n\r\nThe change also adds a JS client implementation as a reference implementation to a client, and also used for tests.\r\n\r\nThe protocol definitions are all in protocol.d.ts.\r\n\r\nNote: Reviewing the final change is probably easier.","created_at":"2015-02-16T04:28:24Z","updated_at":"2015-02-17T22:12:14Z","closed_at":null,"merged_at":null,"merge_commit_sha":"8f01423b62f5a4a006ac66e6aab7f8ce6bd8def6","assignee":null,"milestone":null,"commits_url":"https://api.github.com/repos/Microsoft/TypeScript/pulls/2041/commits","review_comments_url":"https://api.github.com/repos/Microsoft/TypeScript/pulls/2041/comments","review_comment_url":"https://api.github.com/repos/Microsoft/TypeScript/pulls/comments/{number}","comments_url":"https://api.github.com/repos/Microsoft/TypeScript/issues/2041/comments","statuses_url":"https://api.github.com/repos/Microsoft/TypeScript/statuses/cadd57c10fe8036661427c9bf4fa1c22c85658c3","head":{"label":"Microsoft:TSServer","ref":"TSServer","sha":"cadd57c10fe8036661427c9bf4fa1c22c85658c3","user":{"login":"Microsoft","id":6154722,"avatar_url":"https://avatars.githubusercontent.com/u/6154722?v=3","gravatar_id":"","url":"https://api.github.com/users/Microsoft","html_url":"https://github.com/Microsoft","followers_url":"https://api.github.com/users/Microsoft/followers","following_url":"https://api.github.com/users/Microsoft/following{/other_user}","gists_url":"https://api.github.com/users/Microsoft/gists{/gist_id}","starred_url":"https://api.github.com/users/Microsoft/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/Microsoft/subscriptions","organizations_url":"https://api.github.com/users/Microsoft/orgs","repos_url":"https://api.github.com/users/Microsoft/repos","events_url":"https://api.github.com/users/Microsoft/events{/privacy}","received_events_url":"https://api.github.com/users/Microsoft/received_events","type":"Organization","site_admin":false},"repo":{"id":20929025,"name":"TypeScript","full_name":"Microsoft/TypeScript","owner":{"login":"Microsoft","id":6154722,"avatar_url":"https://avatars.githubusercontent.com/u/6154722?v=3","gravatar_id":"","url":"https://api.github.com/users/Microsoft","html_url":"https://github.com/Microsoft","followers_url":"https://api.github.com/users/Microsoft/followers","following_url":"https://api.github.com/users/Microsoft/following{/other_user}","gists_url":"https://api.github.com/users/Microsoft/gists{/gist_id}","starred_url":"https://api.github.com/users/Microsoft/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/Microsoft/subscriptions","organizations_url":"https://api.github.com/users/Microsoft/orgs","repos_url":"https://api.github.com/users/Microsoft/repos","events_url":"https://api.github.com/users/Microsoft/events{/privacy}","received_events_url":"https://api.github.com/users/Microsoft/received_events","type":"Organization","site_admin":false},"private":false,"html_url":"https://github.com/Microsoft/TypeScript","description":"TypeScript is a superset of JavaScript that compiles to clean JavaScript output.","fork":false,"url":"https://api.github.com/repos/Microsoft/TypeScript","forks_url":"https://api.github.com/repos/Microsoft/TypeScript/forks","keys_url":"https://api.github.com/repos/Microsoft/TypeScript/keys{/key_id}","collaborators_url":"https://api.github.com/repos/Microsoft/TypeScript/collaborators{/collaborator}","teams_url":"https://api.github.com/repos/Microsoft/TypeScript/teams","hooks_url":"https://api.github.com/repos/Microsoft/TypeScript/hooks","issue_events_url":"https://api.github.com/repos/Microsoft/TypeScript/issues/events{/number}","events_url":"https://api.github.com/repos/Microsoft/TypeScript/events","assignees_url":"https://api.github.com/repos/Microsoft/TypeScript/assignees{/user}","branches_url":"https://api.github.com/repos/Microsoft/TypeScript/branches{/branch}","tags_url":"https://api.github.com/repos/Microsoft/TypeScript/tags","blobs_url":"https://api.github.com/repos/Microsoft/TypeScript/git/blobs{/sha}","git_tags_url":"https://api.github.com/repos/Microsoft/TypeScript/git/tags{/sha}","git_refs_url":"https://api.github.com/repos/Microsoft/TypeScript/git/refs{/sha}","trees_url":"https://api.github.com/repos/Microsoft/TypeScript/git/trees{/sha}","statuses_url":"https://api.github.com/repos/Microsoft/TypeScript/statuses/{sha}","languages_url":"https://api.github.com/repos/Microsoft/TypeScript/languages","stargazers_url":"https://api.github.com/repos/Microsoft/TypeScript/stargazers","contributors_url":"https://api.github.com/repos/Microsoft/TypeScript/contributors","subscribers_url":"https://api.github.com/repos/Microsoft/TypeScript/subscribers","subscription_url":"https://api.github.com/repos/Microsoft/TypeScript/subscription","commits_url":"https://api.github.com/repos/Microsoft/TypeScript/commits{/sha}","git_commits_url":"https://api.github.com/repos/Microsoft/TypeScript/git/commits{/sha}","comments_url":"https://api.github.com/repos/Microsoft/TypeScript/comments{/number}","issue_comment_url":"https://api.github.com/repos/Microsoft/TypeScript/issues/comments/{number}","contents_url":"https://api.github.com/repos/Microsoft/TypeScript/contents/{+path}","compare_url":"https://api.github.com/repos/Microsoft/TypeScript/compare/{base}...{head}","merges_url":"https://api.github.com/repos/Microsoft/TypeScript/merges","archive_url":"https://api.github.com/repos/Microsoft/TypeScript/{archive_format}{/ref}","downloads_url":"https://api.github.com/repos/Microsoft/TypeScript/downloads","issues_url":"https://api.github.com/repos/Microsoft/TypeScript/issues{/number}","pulls_url":"https://api.github.com/repos/Microsoft/TypeScript/pulls{/number}","milestones_url":"https://api.github.com/repos/Microsoft/TypeScript/milestones{/number}","notifications_url":"https://api.github.com/repos/Microsoft/TypeScript/notifications{?since,all,participating}","labels_url":"https://api.github.com/repos/Microsoft/TypeScript/labels{/name}","releases_url":"https://api.github.com/repos/Microsoft/TypeScript/releases{/id}","created_at":"2014-06-17T15:28:39Z","updated_at":"2015-02-17T18:09:18Z","pushed_at":"2015-02-17T20:39:46Z","git_url":"git://github.com/Microsoft/TypeScript.git","ssh_url":"git@github.com:Microsoft/TypeScript.git","clone_url":"https://github.com/Microsoft/TypeScript.git","svn_url":"https://github.com/Microsoft/TypeScript","homepage":"http://www.typescriptlang.org","size":513544,"stargazers_count":3490,"watchers_count":3490,"language":"JavaScript","has_issues":true,"has_downloads":true,"has_wiki":true,"has_pages":true,"forks_count":328,"mirror_url":null,"open_issues_count":517,"forks":328,"open_issues":517,"watchers":3490,"default_branch":"master"}},"base":{"label":"Microsoft:master","ref":"master","sha":"9f7c252ee0719fe12928c44333270ad197559320","user":{"login":"Microsoft","id":6154722,"avatar_url":"https://avatars.githubusercontent.com/u/6154722?v=3","gravatar_id":"","url":"https://api.github.com/users/Microsoft","html_url":"https://github.com/Microsoft","followers_url":"https://api.github.com/users/Microsoft/followers","following_url":"https://api.github.com/users/Microsoft/following{/other_user}","gists_url":"https://api.github.com/users/Microsoft/gists{/gist_id}","starred_url":"https://api.github.com/users/Microsoft/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/Microsoft/subscriptions","organizations_url":"https://api.github.com/users/Microsoft/orgs","repos_url":"https://api.github.com/users/Microsoft/repos","events_url":"https://api.github.com/users/Microsoft/events{/privacy}","received_events_url":"https://api.github.com/users/Microsoft/received_events","type":"Organization","site_admin":false},"repo":{"id":20929025,"name":"TypeScript","full_name":"Microsoft/TypeScript","owner":{"login":"Microsoft","id":6154722,"avatar_url":"https://avatars.githubusercontent.com/u/6154722?v=3","gravatar_id":"","url":"https://api.github.com/users/Microsoft","html_url":"https://github.com/Microsoft","followers_url":"https://api.github.com/users/Microsoft/followers","following_url":"https://api.github.com/users/Microsoft/following{/other_user}","gists_url":"https://api.github.com/users/Microsoft/gists{/gist_id}","starred_url":"https://api.github.com/users/Microsoft/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/Microsoft/subscriptions","organizations_url":"https://api.github.com/users/Microsoft/orgs","repos_url":"https://api.github.com/users/Microsoft/repos","events_url":"https://api.github.com/users/Microsoft/events{/privacy}","received_events_url":"https://api.github.com/users/Microsoft/received_events","type":"Organization","site_admin":false},"private":false,"html_url":"https://github.com/Microsoft/TypeScript","description":"TypeScript is a superset of JavaScript that compiles to clean JavaScript output.","fork":false,"url":"https://api.github.com/repos/Microsoft/TypeScript","forks_url":"https://api.github.com/repos/Microsoft/TypeScript/forks","keys_url":"https://api.github.com/repos/Microsoft/TypeScript/keys{/key_id}","collaborators_url":"https://api.github.com/repos/Microsoft/TypeScript/collaborators{/collaborator}","teams_url":"https://api.github.com/repos/Microsoft/TypeScript/teams","hooks_url":"https://api.github.com/repos/Microsoft/TypeScript/hooks","issue_events_url":"https://api.github.com/repos/Microsoft/TypeScript/issues/events{/number}","events_url":"https://api.github.com/repos/Microsoft/TypeScript/events","assignees_url":"https://api.github.com/repos/Microsoft/TypeScript/assignees{/user}","branches_url":"https://api.github.com/repos/Microsoft/TypeScript/branches{/branch}","tags_url":"https://api.github.com/repos/Microsoft/TypeScript/tags","blobs_url":"https://api.github.com/repos/Microsoft/TypeScript/git/blobs{/sha}","git_tags_url":"https://api.github.com/repos/Microsoft/TypeScript/git/tags{/sha}","git_refs_url":"https://api.github.com/repos/Microsoft/TypeScript/git/refs{/sha}","trees_url":"https://api.github.com/repos/Microsoft/TypeScript/git/trees{/sha}","statuses_url":"https://api.github.com/repos/Microsoft/TypeScript/statuses/{sha}","languages_url":"https://api.github.com/repos/Microsoft/TypeScript/languages","stargazers_url":"https://api.github.com/repos/Microsoft/TypeScript/stargazers","contributors_url":"https://api.github.com/repos/Microsoft/TypeScript/contributors","subscribers_url":"https://api.github.com/repos/Microsoft/TypeScript/subscribers","subscription_url":"https://api.github.com/repos/Microsoft/TypeScript/subscription","commits_url":"https://api.github.com/repos/Microsoft/TypeScript/commits{/sha}","git_commits_url":"https://api.github.com/repos/Microsoft/TypeScript/git/commits{/sha}","comments_url":"https://api.github.com/repos/Microsoft/TypeScript/comments{/number}","issue_comment_url":"https://api.github.com/repos/Microsoft/TypeScript/issues/comments/{number}","contents_url":"https://api.github.com/repos/Microsoft/TypeScript/contents/{+path}","compare_url":"https://api.github.com/repos/Microsoft/TypeScript/compare/{base}...{head}","merges_url":"https://api.github.com/repos/Microsoft/TypeScript/merges","archive_url":"https://api.github.com/repos/Microsoft/TypeScript/{archive_format}{/ref}","downloads_url":"https://api.github.com/repos/Microsoft/TypeScript/downloads","issues_url":"https://api.github.com/repos/Microsoft/TypeScript/issues{/number}","pulls_url":"https://api.github.com/repos/Microsoft/TypeScript/pulls{/number}","milestones_url":"https://api.github.com/repos/Microsoft/TypeScript/milestones{/number}","notifications_url":"https://api.github.com/repos/Microsoft/TypeScript/notifications{?since,all,participating}","labels_url":"https://api.github.com/repos/Microsoft/TypeScript/labels{/name}","releases_url":"https://api.github.com/repos/Microsoft/TypeScript/releases{/id}","created_at":"2014-06-17T15:28:39Z","updated_at":"2015-02-17T18:09:18Z","pushed_at":"2015-02-17T20:39:46Z","git_url":"git://github.com/Microsoft/TypeScript.git","ssh_url":"git@github.com:Microsoft/TypeScript.git","clone_url":"https://github.com/Microsoft/TypeScript.git","svn_url":"https://github.com/Microsoft/TypeScript","homepage":"http://www.typescriptlang.org","size":513544,"stargazers_count":3490,"watchers_count":3490,"language":"JavaScript","has_issues":true,"has_downloads":true,"has_wiki":true,"has_pages":true,"forks_count":328,"mirror_url":null,"open_issues_count":517,"forks":328,"open_issues":517,"watchers":3490,"default_branch":"master"}},"_links":{"self":{"href":"https://api.github.com/repos/Microsoft/TypeScript/pulls/2041"},"html":{"href":"https://github.com/Microsoft/TypeScript/pull/2041"},"issue":{"href":"https://api.github.com/repos/Microsoft/TypeScript/issues/2041"},"comments":{"href":"https://api.github.com/repos/Microsoft/TypeScript/issues/2041/comments"},"review_comments":{"href":"https://api.github.com/repos/Microsoft/TypeScript/pulls/2041/comments"},"review_comment":{"href":"https://api.github.com/repos/Microsoft/TypeScript/pulls/comments/{number}"},"commits":{"href":"https://api.github.com/repos/Microsoft/TypeScript/pulls/2041/commits"},"statuses":{"href":"https://api.github.com/repos/Microsoft/TypeScript/statuses/cadd57c10fe8036661427c9bf4fa1c22c85658c3"}}}}