diff --git a/.gitignore b/.gitignore index c342f71ee..3c3629e64 100644 --- a/.gitignore +++ b/.gitignore @@ -1,7 +1 @@ -.tscache -/.ntvs_analysis.dat -/.ntvs_analysis.dat.tmp -obj/Debug/VSProj.njsproj.FileListAbsolute.txt -.baseDir.ts -node_modules/ -/typings/ +node_modules diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md index bbe065a3b..399b27f0a 100644 --- a/CONTRIBUTING.md +++ b/CONTRIBUTING.md @@ -12,10 +12,10 @@ Simply clone the repository, and then link the folder into your packages directo git clone https://github.com/TypeStrong/atom-typescript.git cd atom-typescript npm install -apm link -l +apm link -d ``` -You still have to reload atom with `ctrl+alt+r` to test your changes. +You still have to reload atom with `ctrl+alt+r` or `ctrl+shift+f5` to test your changes. Now you can use atom-typescript *to develop atom-typescript*. This is covered more in the workflow https://github.com/TypeStrong/atom-typescript/blob/master/CONTRIBUTING.md#workflow @@ -55,44 +55,22 @@ Additional Notes: Some shortcuts: * `ctrl+alt+i` will open the dev tools. These are the same Chrome dev tools you are familiar with. Feel free to inspect elements. This will come handy when doing UI or even seeing why a particular code element is highlighted in some way. -* `ctrl+alt+r` will reload the entire atom instance. - -### Debugging -There are *lots of ways* to do this. The ones we use right now: - -* You can do `console.error` from `projectService` and it will get logged to the atom's console (`ctrl+alt+i`). That's the quickest. -* You can call `projectService` in `sync` from the UI thread if you want to debug using atom's built in tools (`ctrl+alt+i`). Set `debugSync` to true in `./lib/worker/debug.ts`, and it takes care of the rest. - -Also [if there is an error in `projectService` it gets logged to the console as a rejected promise](https://raw.githubusercontent.com/TypeStrong/atom-typescript-examples/master/screens/debugPromises.gif). +* `ctrl+alt+r` or `ctrl+shift+f5` will reload the entire atom instance. ### General Steps 1. We open `atom-typescript` in one atom window -1. We have [`atom-typescript-examples`](https://github.com/TypeStrong/atom-typescript-examples) open in another atom window +1. We have [`atom-typescript-examples`](https://github.com/TypeStrong/atom-typescript-examples) open in another atom window as such: `atom --dev ` 1. We make changes to `atom-typescript` and save to get the JS. -1. We reload the `atom-typescript-examples` window to see the effects of our change. +1. We reload the `atom-typescript-examples` (`ctrl+alt+r` or `ctrl+shift+f5`) window to see the effects of our change. 1. Only reload the `atom-typescript` window once we are sure that our new code is functional. #### When you break atom-typescript during development -This shouldn't happen as long as you leave the `atom-typescript` window untouched and do testing in another atom instance. If you reload the `atom-typescript` window thinking its going to be stable but it turns out to be unstable do one of the following: +This shouldn't happen as long as you start the `atom-typescript` window _without_ the `--dev` flag, and do testing in another atom instance. If you reload the `atom-typescript` window thinking its going to be stable but it turns out to be unstable do one of the following: * Discard the *JavaScript* changes that you think broke it and reload the atom instance. -* Run `grunt` and leave it running to compile your atomts changes (as atomts is going to be out of order) -* Open up the visual studio project (at your own risk, we do not keep this up to date!) - -## Architecture -We wrap the `languageService` + our custom `languageServiceHost` + [`projectFile`](https://github.com/TypeStrong/atom-typescript/blob/master/docs/tsconfig.md) into a `Project` (code in `Project.ts` in the `lang` folder). The functions that interact with this `project` are exposed from `projectService` ([the query / response section](https://github.com/TypeStrong/atom-typescript/blob/6fbf860eaf971baa3aca939626db553898cb40db/lib/main/lang/projectService.ts#L58-L244)). `projectService` is where you would add new features that interact with the language service. All this code is `sync` and can be tested / run on any node instance. Be careful not to *leave* `console.log` in this code (as we use `stdio` to make this code `async`) or use `atom` specific APIs (as it may not be in the UI thread). - -We make this code `async`(and promise based) by: -* **Single line:** (e.g. `export var echo = childQuery(projectService.echo);`) for every new call to get good compile time safety ([see the code in `parent.ts`](https://github.com/TypeStrong/atom-typescript/blob/b0a862cf209d18982875d5c38e3a655594316e9a/lib/worker/parent.ts#L148-L158)). - -### Additional Notes: -* `childQuery` takes the signature of the `sync` function from `projectService` of the form `Query->Response` and automatically creates an `async` function of the form `Query->Promise`. The function body from `projectService` is not used, just the function *name* and the *type information* is. -* We automatically add all functions exported from `projectService` in the list of functions that the child uses to respond to by name. ([see code in `child.ts`](https://github.com/TypeStrong/atom-typescript/blob/b0a862cf209d18982875d5c38e3a655594316e9a/lib/worker/child.ts#L48-L51)). Here we are not concerned with the *type information*. Instead we will actively *call the function* added to responders by *name*. -* We spawn a separate `atom` (or `node` on windows) instance and use `ipc` ([see code in `parent.ts`](https://github.com/TypeStrong/atom-typescript/blob/b0a862cf209d18982875d5c38e3a655594316e9a/lib/worker/parent.ts#L4-L141)). Also [reason for not using WebWorkers](https://github.com/atom/atom-shell/issues/797). - -Advantage: you only need to define the query/response interface once (in `projectService.ts`) and write it in a testable `sync` manner. The parent code is never out of sync from the function definition (thanks to `childQuery`). Adding new functions is done is a typesafe way as you would write any other sync function + additionally using only one additional line of code in `parent.ts` (`childQuery`). ## Language Service Documentation The TypeScript Language service docs: https://github.com/Microsoft/TypeScript/wiki/Using-the-Compiler-API +The `tsserver` protocol definitions https://github.com/Microsoft/TypeScript/blob/master/lib/protocol.d.ts ## Showing errors in atom Done using the `linter` plugin. If you think about it. TypeScript is really just a super powerful version of `jshint` and that is the reason to use `linter` for errors. @@ -101,17 +79,3 @@ Just look at `linter.ts` in our code. ## Grammar Please see https://github.com/TypeStrong/atom-typescript/tree/master/docs/grammar.md - - -## QuickFix -The quickest way is to copy an existing one located in the [quick fix directory](https://github.com/TypeStrong/atom-typescript/tree/a91f7e0c935ed2bdc2c642350af50a7a5aed70ad/lib/main/lang/fixmyts/quickFixes). Copy one of these files into a new quick fix. - -Quick fixes need to implement the `QuickFix` interface ([code here](https://github.com/TypeStrong/atom-typescript/blob/a91f7e0c935ed2bdc2c642350af50a7a5aed70ad/lib/main/lang/fixmyts/quickFix.ts#L46-L53)). - -Once you have the quickfix created just put it into the [quickfix registry](https://github.com/TypeStrong/atom-typescript/blob/a91f7e0c935ed2bdc2c642350af50a7a5aed70ad/lib/main/lang/fixmyts/quickFixRegistry.ts#L14-L24) so that the infrastructure picks it up. - -**Additional Tips** : One indespensible tool when creating a quick fix is the [AST viewer](https://github.com/TypeStrong/atom-typescript#ast-visualizer) which allows you to investigate the TypeScript language service view of the file. - -# Video - -A video on some of the internals : https://www.youtube.com/watch?v=WOuNb2MGR4o diff --git a/README.md b/README.md index c72064872..11cbfa251 100644 --- a/README.md +++ b/README.md @@ -4,6 +4,8 @@ JavaScript developers can now just open a `.ts` file and start hacking away like they are used to. No `grunt` no `Visual Studio`. Just pure coding. +**NOTE**: This branch contains a major rewrite (**v11**) of the `atom-typescript` plugin that is lighter and faster, but lacks a few major features that you might miss. The previous version is still available in the `legacy` branch and will continue to receive minor bugfixes, but I wouldn't count on any new developments. + ## Installation 1. Install [atom](https://atom.io). @@ -15,9 +17,9 @@ JavaScript developers can now just open a `.ts` file and start hacking away like ## Reviews *Featured on the TypeScript home page under tools http://www.typescriptlang.org/* and [demoed by **Anders Hejlsberg**](https://twitter.com/schwarty/status/593858817894404096). -"I was shocked at how good it felt to poke around on the compiler with it." [Jonathan Turner](https://twitter.com/jntrnr) -"And guess what, it worked perfectly. Like everything else! Faster than Visual Studio!" [Daniel Earwicker](http://stackoverflow.com/users/27423/daniel-earwicker) -"It's a thing of beauty - they had me at '*Type information on hover*'. Discovering `tsconfig.json` support as well was just an enormous bonus." [John Reilly](https://twitter.com/johnny_reilly) +"I was shocked at how good it felt to poke around on the compiler with it." [Jonathan Turner](https://twitter.com/jntrnr) +"And guess what, it worked perfectly. Like everything else! Faster than Visual Studio!" [Daniel Earwicker](http://stackoverflow.com/users/27423/daniel-earwicker) +"It's a thing of beauty - they had me at '*Type information on hover*'. Discovering `tsconfig.json` support as well was just an enormous bonus." [John Reilly](https://twitter.com/johnny_reilly) "This may be your best option for editing TypeScript at the moment - very nice!" [Rasmus Schultz](https://twitter.com/mindplaydk) [*Add yours!*](https://github.com/TypeStrong/atom-typescript/issues/66) @@ -30,26 +32,11 @@ JavaScript developers can now just open a `.ts` file and start hacking away like * Project Context Support (`tsconfig.json`) * Project Build Support * `package.json` Support -* React Support -* Format code (configurable to be on save) * Goto Declaration * Find References * Block comment and uncomment -* Goto history (goto next/previous error in open files, goto next/previous build) -* Auto indent for new lines -* TypeScript context menu -* Symbols in Project -* Symbols in File -* Semantic View * Rename refactoring -* Quick Fix -* Toggle Breakpoint * Common Snippets -* `import` / `/// - - - Debug - 2.0 - {ecf0e459-f515-4390-9257-4c7888cc0494} - - ShowAllFiles - Gruntfile.js - . - . - {3AF33F2E-1136-4D97-BBB7-1795711AC8B8};{349c5851-65df-11da-9384-00065b846f21};{9092AA53-FB77-4645-B42D-1CCCA6BD08BD} - False - CommonJS - true - 11.0 - $(MSBuildExtensionsPath32)\Microsoft\VisualStudio\v$(VisualStudioVersion) - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - False - True - 0 - / - http://localhost:48022/ - False - True - http://localhost:1337 - False - - - - - - - CurrentPage - True - False - False - False - - - - - - - - - False - False - - - - - diff --git a/VSProj.sln b/VSProj.sln deleted file mode 100644 index 1a1a91e3b..000000000 --- a/VSProj.sln +++ /dev/null @@ -1,22 +0,0 @@ - -Microsoft Visual Studio Solution File, Format Version 12.00 -# Visual Studio 2013 -VisualStudioVersion = 12.0.31101.0 -MinimumVisualStudioVersion = 10.0.40219.1 -Project("{9092AA53-FB77-4645-B42D-1CCCA6BD08BD}") = "VSProj", "VSProj.njsproj", "{ECF0E459-F515-4390-9257-4C7888CC0494}" -EndProject -Global - GlobalSection(SolutionConfigurationPlatforms) = preSolution - Debug|Any CPU = Debug|Any CPU - Release|Any CPU = Release|Any CPU - EndGlobalSection - GlobalSection(ProjectConfigurationPlatforms) = postSolution - {ECF0E459-F515-4390-9257-4C7888CC0494}.Debug|Any CPU.ActiveCfg = Debug|Any CPU - {ECF0E459-F515-4390-9257-4C7888CC0494}.Debug|Any CPU.Build.0 = Debug|Any CPU - {ECF0E459-F515-4390-9257-4C7888CC0494}.Release|Any CPU.ActiveCfg = Release|Any CPU - {ECF0E459-F515-4390-9257-4C7888CC0494}.Release|Any CPU.Build.0 = Release|Any CPU - EndGlobalSection - GlobalSection(SolutionProperties) = preSolution - HideSolutionNode = FALSE - EndGlobalSection -EndGlobal diff --git a/dist/client/callbacks.js b/dist/client/callbacks.js new file mode 100644 index 000000000..c0473d618 --- /dev/null +++ b/dist/client/callbacks.js @@ -0,0 +1,46 @@ +"use strict"; +Object.defineProperty(exports, "__esModule", { value: true }); +// Callbacks keeps track of all the outstanding requests +class Callbacks { + constructor(onPendingChange) { + this.onPendingChange = onPendingChange; + this.callbacks = new Map(); + } + add(seq, command) { + return new Promise((resolve, reject) => { + this.callbacks.set(seq, { + name: command, + resolve, + reject, + started: Date.now() + }); + this.onPendingChange(this.pending()); + }); + } + // pending returns names of requests waiting for a response + pending() { + const pending = []; + for (const { name } of this.callbacks.values()) { + pending.push(name); + } + return pending; + } + rejectAll(error) { + for (const { reject } of this.callbacks.values()) { + reject(error); + } + this.callbacks.clear(); + this.onPendingChange(this.pending()); + } + // Remove and return a Request object, if one exists + remove(seq) { + const req = this.callbacks.get(seq); + this.callbacks.delete(seq); + if (req) { + this.onPendingChange(this.pending()); + } + return req; + } +} +exports.Callbacks = Callbacks; +//# sourceMappingURL=callbacks.js.map \ No newline at end of file diff --git a/dist/client/callbacks.js.map b/dist/client/callbacks.js.map new file mode 100644 index 000000000..9641d6cde --- /dev/null +++ b/dist/client/callbacks.js.map @@ -0,0 +1 @@ +{"version":3,"file":"callbacks.js","sourceRoot":"","sources":["../../lib/client/callbacks.ts"],"names":[],"mappings":";;AASA,wDAAwD;AACxD;IAGE,YAAoB,eAA4C;QAA5C,oBAAe,GAAf,eAAe,CAA6B;QAFxD,cAAS,GAAyB,IAAI,GAAG,EAAE,CAAA;IAEgB,CAAC;IAEpE,GAAG,CAAC,GAAW,EAAE,OAAe;QAC9B,MAAM,CAAC,IAAI,OAAO,CAAC,CAAC,OAAO,EAAE,MAAM;YACjC,IAAI,CAAC,SAAS,CAAC,GAAG,CAAC,GAAG,EAAE;gBACtB,IAAI,EAAE,OAAO;gBACb,OAAO;gBACP,MAAM;gBACN,OAAO,EAAE,IAAI,CAAC,GAAG,EAAE;aACpB,CAAC,CAAA;YAEF,IAAI,CAAC,eAAe,CAAC,IAAI,CAAC,OAAO,EAAE,CAAC,CAAA;QACtC,CAAC,CAAC,CAAA;IACJ,CAAC;IAED,2DAA2D;IAC3D,OAAO;QACL,MAAM,OAAO,GAAa,EAAE,CAAA;QAE5B,GAAG,CAAC,CAAC,MAAM,EAAC,IAAI,EAAC,IAAI,IAAI,CAAC,SAAS,CAAC,MAAM,EAAE,CAAC,CAAC,CAAC;YAC7C,OAAO,CAAC,IAAI,CAAC,IAAI,CAAC,CAAA;QACpB,CAAC;QAED,MAAM,CAAC,OAAO,CAAA;IAChB,CAAC;IAED,SAAS,CAAC,KAAU;QAClB,GAAG,CAAC,CAAC,MAAM,EAAC,MAAM,EAAC,IAAI,IAAI,CAAC,SAAS,CAAC,MAAM,EAAE,CAAC,CAAC,CAAC;YAC/C,MAAM,CAAC,KAAK,CAAC,CAAA;QACf,CAAC;QAED,IAAI,CAAC,SAAS,CAAC,KAAK,EAAE,CAAA;QACtB,IAAI,CAAC,eAAe,CAAC,IAAI,CAAC,OAAO,EAAE,CAAC,CAAA;IACtC,CAAC;IAED,oDAAoD;IACpD,MAAM,CAAC,GAAW;QAChB,MAAM,GAAG,GAAG,IAAI,CAAC,SAAS,CAAC,GAAG,CAAC,GAAG,CAAC,CAAA;QACnC,IAAI,CAAC,SAAS,CAAC,MAAM,CAAC,GAAG,CAAC,CAAA;QAC1B,EAAE,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC;YACR,IAAI,CAAC,eAAe,CAAC,IAAI,CAAC,OAAO,EAAE,CAAC,CAAA;QACtC,CAAC;QACD,MAAM,CAAC,GAAG,CAAA;IACZ,CAAC;CACF;AA/CD,8BA+CC"} \ No newline at end of file diff --git a/dist/client/client.js b/dist/client/client.js new file mode 100644 index 000000000..79c1d8c6b --- /dev/null +++ b/dist/client/client.js @@ -0,0 +1,253 @@ +"use strict"; +Object.defineProperty(exports, "__esModule", { value: true }); +const tslib_1 = require("tslib"); +const atom_1 = require("atom"); +const callbacks_1 = require("./callbacks"); +const events_1 = require("events"); +const stream_1 = require("stream"); +const byline = require("byline"); +// Set this to true to start tsserver with node --inspect +const INSPECT_TSSERVER = false; +exports.CommandWithResponse = new Set([ + "compileOnSaveAffectedFileList", + "compileOnSaveEmitFile", + "completionEntryDetails", + "completions", + "configure", + "definition", + "format", + "occurrences", + "projectInfo", + "quickinfo", + "references", + "reload", + "rename", +]); +class TypescriptServiceClient { + constructor(tsServerPath, version) { + this.tsServerPath = tsServerPath; + this.version = version; + this.events = new events_1.EventEmitter(); + this.seq = 0; + /** Extra args passed to the tsserver executable */ + this.tsServerArgs = []; + this.emitPendingRequests = (pending) => { + this.events.emit("pendingRequestsChange", pending); + }; + this.onMessage = (res) => { + if (isResponse(res)) { + const req = this.callbacks.remove(res.request_seq); + if (req) { + if (window.atom_typescript_debug) { + console.log("received response for", res.command, "in", Date.now() - req.started, "ms", "with data", res.body); + } + if (res.success) { + req.resolve(res); + } + else { + req.reject(new Error(res.message)); + } + } + else { + console.warn("unexpected response:", res); + } + } + else if (isEvent(res)) { + if (window.atom_typescript_debug) { + console.log("received event", res); + } + this.events.emit(res.event, res.body); + } + }; + this.callbacks = new callbacks_1.Callbacks(this.emitPendingRequests); + } + executeChange(args) { + return this.execute("change", args); + } + executeClose(args) { + return this.execute("close", args); + } + executeCompileOnSaveAffectedFileList(args) { + return this.execute("compileOnSaveAffectedFileList", args); + } + executeCompileOnSaveEmitFile(args) { + return this.execute("compileOnSaveEmitFile", args); + } + executeCompletions(args) { + return this.execute("completions", args); + } + executeCompletionDetails(args) { + return this.execute("completionEntryDetails", args); + } + executeConfigure(args) { + return this.execute("configure", args); + } + executeDefinition(args) { + return this.execute("definition", args); + } + executeFormat(args) { + return this.execute("format", args); + } + executeGetErr(args) { + return this.execute("geterr", args); + } + executeGetErrForProject(args) { + return this.execute("geterrForProject", args); + } + executeOccurances(args) { + return this.execute("occurrences", args); + } + executeOpen(args) { + return this.execute("open", args); + } + executeProjectInfo(args) { + return this.execute("projectInfo", args); + } + executeQuickInfo(args) { + return this.execute("quickinfo", args); + } + executeReferences(args) { + return this.execute("references", args); + } + executeReload(args) { + return this.execute("reload", args); + } + executeRename(args) { + return this.execute("rename", args); + } + executeSaveTo(args) { + return this.execute("saveto", args); + } + execute(command, args) { + return tslib_1.__awaiter(this, void 0, void 0, function* () { + if (!this.serverPromise) { + throw new Error("Server is not running"); + } + return this.sendRequest(yield this.serverPromise, command, args, exports.CommandWithResponse.has(command)); + }); + } + on(name, listener) { + this.events.on(name, listener); + return () => { + this.events.removeListener(name, listener); + }; + } + sendRequest(cp, command, args, expectResponse) { + const req = { + seq: this.seq++, + command, + arguments: args + }; + if (window.atom_typescript_debug) { + console.log("sending request", command, "with args", args); + } + setImmediate(() => { + try { + cp.stdin.write(JSON.stringify(req) + "\n"); + } + catch (error) { + const callback = this.callbacks.remove(req.seq); + if (callback) { + callback.reject(error); + } + else { + console.error(error); + } + } + }); + if (expectResponse) { + return this.callbacks.add(req.seq, command); + } + } + startServer() { + if (!this.serverPromise) { + let lastStderrOutput; + let reject; + const exitHandler = (result) => { + const err = typeof result === "number" ? + new Error("exited with code: " + result) : result; + console.error("tsserver: ", err); + this.callbacks.rejectAll(err); + reject(err); + this.serverPromise = undefined; + setImmediate(() => { + let detail = err && err.stack || ""; + if (lastStderrOutput) { + detail = "Last output from tsserver:\n" + lastStderrOutput + "\n \n" + detail; + } + atom.notifications.addError("Typescript quit unexpectedly", { + detail, + dismissable: true, + }); + }); + }; + return this.serverPromise = new Promise((resolve, _reject) => { + reject = _reject; + if (window.atom_typescript_debug) { + console.log("starting", this.tsServerPath); + } + const cp = startServer(this.tsServerPath, this.tsServerArgs); + cp.once("error", exitHandler); + cp.once("exit", exitHandler); + // Pipe both stdout and stderr appropriately + messageStream(cp.stdout).on("data", this.onMessage); + cp.stderr.on("data", data => { + console.warn("tsserver stderr:", lastStderrOutput = data.toString()); + }); + // We send an unknown command to verify that the server is working. + this.sendRequest(cp, "ping", null, true).then(res => resolve(cp), err => resolve(cp)); + }); + } + else { + throw new Error(`Server already started: ${this.tsServerPath}`); + } + } +} +exports.TypescriptServiceClient = TypescriptServiceClient; +function startServer(tsServerPath, tsServerArgs) { + if (INSPECT_TSSERVER) { + return new atom_1.BufferedProcess({ + command: "node", + args: ["--inspect", tsServerPath].concat(tsServerArgs), + }).process; + } + else { + return new atom_1.BufferedNodeProcess({ + command: tsServerPath, + args: tsServerArgs + }).process; + } +} +function isEvent(res) { + return res.type === "event"; +} +function isResponse(res) { + return res.type === "response"; +} +function messageStream(input) { + return input.pipe(byline()).pipe(new MessageStream()); +} +/** Helper to parse the tsserver output stream to a message stream */ +class MessageStream extends stream_1.Transform { + constructor() { + super({ objectMode: true }); + } + _transform(buf, encoding, callback) { + const line = buf.toString(); + try { + if (line.startsWith("{")) { + this.push(JSON.parse(line)); + } + else if (!line.startsWith("Content-Length:")) { + console.warn(line); + } + } + catch (error) { + console.error("client: failed to parse: ", line); + } + finally { + callback(null); + } + } +} +//# sourceMappingURL=client.js.map \ No newline at end of file diff --git a/dist/client/client.js.map b/dist/client/client.js.map new file mode 100644 index 000000000..7d1653538 --- /dev/null +++ b/dist/client/client.js.map @@ -0,0 +1 @@ +{"version":3,"file":"client.js","sourceRoot":"","sources":["../../lib/client/client.ts"],"names":[],"mappings":";;;AACA,+BAAyD;AACzD,2CAAqC;AAErC,mCAAmC;AACnC,mCAA0C;AAC1C,iCAAiC;AAEjC,yDAAyD;AACzD,MAAM,gBAAgB,GAAG,KAAK,CAAA;AAEjB,QAAA,mBAAmB,GAAG,IAAI,GAAG,CAAC;IACzC,+BAA+B;IAC/B,uBAAuB;IACvB,wBAAwB;IACxB,aAAa;IACb,WAAW;IACX,YAAY;IACZ,QAAQ;IACR,aAAa;IACb,aAAa;IACb,WAAW;IACX,YAAY;IACZ,QAAQ;IACR,QAAQ;CACT,CAAC,CAAA;AAEF;IAiBE,YAAmB,YAAoB,EAAS,OAAe;QAA5C,iBAAY,GAAZ,YAAY,CAAQ;QAAS,YAAO,GAAP,OAAO,CAAQ;QAZvD,WAAM,GAAG,IAAI,qBAAY,EAAE,CAAA;QAC3B,QAAG,GAAG,CAAC,CAAA;QAQf,mDAAmD;QAC1C,iBAAY,GAAa,EAAE,CAAA;QAqF5B,wBAAmB,GAAG,CAAC,OAAiB;YAC9C,IAAI,CAAC,MAAM,CAAC,IAAI,CAAC,uBAAuB,EAAE,OAAO,CAAC,CAAA;QACpD,CAAC,CAAA;QAEO,cAAS,GAAG,CAAC,GAAuC;YAC1D,EAAE,CAAC,CAAC,UAAU,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC;gBACpB,MAAM,GAAG,GAAG,IAAI,CAAC,SAAS,CAAC,MAAM,CAAC,GAAG,CAAC,WAAW,CAAC,CAAA;gBAClD,EAAE,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC;oBACR,EAAE,CAAC,CAAC,MAAM,CAAC,qBAAqB,CAAC,CAAC,CAAC;wBACjC,OAAO,CAAC,GAAG,CAAC,uBAAuB,EAAE,GAAG,CAAC,OAAO,EAAE,IAAI,EAAE,IAAI,CAAC,GAAG,EAAE,GAAG,GAAG,CAAC,OAAO,EAAE,IAAI,EAAE,WAAW,EAAE,GAAG,CAAC,IAAI,CAAC,CAAA;oBAChH,CAAC;oBAED,EAAE,CAAC,CAAC,GAAG,CAAC,OAAO,CAAC,CAAC,CAAC;wBAChB,GAAG,CAAC,OAAO,CAAC,GAAG,CAAC,CAAA;oBAClB,CAAC;oBAAC,IAAI,CAAC,CAAC;wBACN,GAAG,CAAC,MAAM,CAAC,IAAI,KAAK,CAAC,GAAG,CAAC,OAAO,CAAC,CAAC,CAAA;oBACpC,CAAC;gBACH,CAAC;gBAAC,IAAI,CAAC,CAAC;oBACN,OAAO,CAAC,IAAI,CAAC,sBAAsB,EAAE,GAAG,CAAC,CAAA;gBAC3C,CAAC;YACH,CAAC;YAAC,IAAI,CAAC,EAAE,CAAC,CAAC,OAAO,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC;gBACxB,EAAE,CAAC,CAAC,MAAM,CAAC,qBAAqB,CAAC,CAAC,CAAC;oBACjC,OAAO,CAAC,GAAG,CAAC,gBAAgB,EAAE,GAAG,CAAC,CAAA;gBACpC,CAAC;gBAED,IAAI,CAAC,MAAM,CAAC,IAAI,CAAC,GAAG,CAAC,KAAK,EAAE,GAAG,CAAC,IAAI,CAAC,CAAA;YACvC,CAAC;QACH,CAAC,CAAA;QA7GC,IAAI,CAAC,SAAS,GAAG,IAAI,qBAAS,CAAC,IAAI,CAAC,mBAAmB,CAAC,CAAA;IAC1D,CAAC;IAED,aAAa,CAAC,IAAgC;QAC5C,MAAM,CAAC,IAAI,CAAC,OAAO,CAAC,QAAQ,EAAE,IAAI,CAAC,CAAA;IACrC,CAAC;IACD,YAAY,CAAC,IAA8B;QACzC,MAAM,CAAC,IAAI,CAAC,OAAO,CAAC,OAAO,EAAE,IAAI,CAAC,CAAA;IACpC,CAAC;IACD,oCAAoC,CAAC,IAA8B;QACjE,MAAM,CAAC,IAAI,CAAC,OAAO,CAAC,+BAA+B,EAAE,IAAI,CAAC,CAAA;IAC5D,CAAC;IACD,4BAA4B,CAAC,IAA+C;QAC1E,MAAM,CAAC,IAAI,CAAC,OAAO,CAAC,uBAAuB,EAAE,IAAI,CAAC,CAAA;IACpD,CAAC;IACD,kBAAkB,CAAC,IAAqC;QACtD,MAAM,CAAC,IAAI,CAAC,OAAO,CAAC,aAAa,EAAE,IAAI,CAAC,CAAA;IAC1C,CAAC;IACD,wBAAwB,CAAC,IAA2C;QAClE,MAAM,CAAC,IAAI,CAAC,OAAO,CAAC,wBAAwB,EAAE,IAAI,CAAC,CAAA;IACrD,CAAC;IACD,gBAAgB,CAAC,IAAwC;QACvD,MAAM,CAAC,IAAI,CAAC,OAAO,CAAC,WAAW,EAAE,IAAI,CAAC,CAAA;IACxC,CAAC;IACD,iBAAiB,CAAC,IAAsC;QACtD,MAAM,CAAC,IAAI,CAAC,OAAO,CAAC,YAAY,EAAE,IAAI,CAAC,CAAA;IACzC,CAAC;IACD,aAAa,CAAC,IAAgC;QAC5C,MAAM,CAAC,IAAI,CAAC,OAAO,CAAC,QAAQ,EAAE,IAAI,CAAC,CAAA;IACrC,CAAC;IACD,aAAa,CAAC,IAAgC;QAC5C,MAAM,CAAC,IAAI,CAAC,OAAO,CAAC,QAAQ,EAAE,IAAI,CAAC,CAAA;IACrC,CAAC;IACD,uBAAuB,CAAC,IAA0C;QAChE,MAAM,CAAC,IAAI,CAAC,OAAO,CAAC,kBAAkB,EAAE,IAAI,CAAC,CAAA;IAC/C,CAAC;IACD,iBAAiB,CAAC,IAAsC;QACtD,MAAM,CAAC,IAAI,CAAC,OAAO,CAAC,aAAa,EAAE,IAAI,CAAC,CAAA;IAC1C,CAAC;IACD,WAAW,CAAC,IAA8B;QACxC,MAAM,CAAC,IAAI,CAAC,OAAO,CAAC,MAAM,EAAE,IAAI,CAAC,CAAA;IACnC,CAAC;IACD,kBAAkB,CAAC,IAAqC;QACtD,MAAM,CAAC,IAAI,CAAC,OAAO,CAAC,aAAa,EAAE,IAAI,CAAC,CAAA;IAC1C,CAAC;IACD,gBAAgB,CAAC,IAAsC;QACrD,MAAM,CAAC,IAAI,CAAC,OAAO,CAAC,WAAW,EAAE,IAAI,CAAC,CAAA;IACxC,CAAC;IACD,iBAAiB,CAAC,IAAsC;QACtD,MAAM,CAAC,IAAI,CAAC,OAAO,CAAC,YAAY,EAAE,IAAI,CAAC,CAAA;IACzC,CAAC;IACD,aAAa,CAAC,IAAgC;QAC5C,MAAM,CAAC,IAAI,CAAC,OAAO,CAAC,QAAQ,EAAE,IAAI,CAAC,CAAA;IACrC,CAAC;IACD,aAAa,CAAC,IAAgC;QAC5C,MAAM,CAAC,IAAI,CAAC,OAAO,CAAC,QAAQ,EAAE,IAAI,CAAC,CAAA;IACrC,CAAC;IACD,aAAa,CAAC,IAAgC;QAC5C,MAAM,CAAC,IAAI,CAAC,OAAO,CAAC,QAAQ,EAAE,IAAI,CAAC,CAAA;IACrC,CAAC;IAEa,OAAO,CAAC,OAAe,EAAE,IAAS;;YAC9C,EAAE,CAAC,CAAC,CAAC,IAAI,CAAC,aAAa,CAAC,CAAC,CAAC;gBACxB,MAAM,IAAI,KAAK,CAAC,uBAAuB,CAAC,CAAA;YAC1C,CAAC;YAED,MAAM,CAAC,IAAI,CAAC,WAAW,CAAC,MAAM,IAAI,CAAC,aAAa,EAAE,OAAO,EAAE,IAAI,EAAE,2BAAmB,CAAC,GAAG,CAAC,OAAO,CAAC,CAAC,CAAA;QACpG,CAAC;KAAA;IAOD,EAAE,CAAC,IAAY,EAAE,QAA8B;QAC7C,IAAI,CAAC,MAAM,CAAC,EAAE,CAAC,IAAI,EAAE,QAAQ,CAAC,CAAA;QAE9B,MAAM,CAAC;YACL,IAAI,CAAC,MAAM,CAAC,cAAc,CAAC,IAAI,EAAE,QAAQ,CAAC,CAAA;QAC5C,CAAC,CAAA;IACH,CAAC;IAkCO,WAAW,CAAC,EAAgB,EAAE,OAAe,EAAE,IAAS,EAAE,cAAuB;QAEvF,MAAM,GAAG,GAAG;YACV,GAAG,EAAE,IAAI,CAAC,GAAG,EAAE;YACf,OAAO;YACP,SAAS,EAAE,IAAI;SAChB,CAAA;QAED,EAAE,CAAC,CAAC,MAAM,CAAC,qBAAqB,CAAC,CAAC,CAAC;YACjC,OAAO,CAAC,GAAG,CAAC,iBAAiB,EAAE,OAAO,EAAE,WAAW,EAAE,IAAI,CAAC,CAAA;QAC5D,CAAC;QAED,YAAY,CAAC;YACX,IAAI,CAAC;gBACH,EAAE,CAAC,KAAK,CAAC,KAAK,CAAC,IAAI,CAAC,SAAS,CAAC,GAAG,CAAC,GAAG,IAAI,CAAC,CAAA;YAC5C,CAAC;YAAC,KAAK,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC;gBACf,MAAM,QAAQ,GAAG,IAAI,CAAC,SAAS,CAAC,MAAM,CAAC,GAAG,CAAC,GAAG,CAAC,CAAA;gBAC/C,EAAE,CAAC,CAAC,QAAQ,CAAC,CAAC,CAAC;oBACb,QAAQ,CAAC,MAAM,CAAC,KAAK,CAAC,CAAA;gBACxB,CAAC;gBAAC,IAAI,CAAC,CAAC;oBACN,OAAO,CAAC,KAAK,CAAC,KAAK,CAAC,CAAA;gBACtB,CAAC;YACH,CAAC;QACH,CAAC,CAAC,CAAA;QAEF,EAAE,CAAC,CAAC,cAAc,CAAC,CAAC,CAAC;YACnB,MAAM,CAAC,IAAI,CAAC,SAAS,CAAC,GAAG,CAAC,GAAG,CAAC,GAAG,EAAE,OAAO,CAAC,CAAA;QAC7C,CAAC;IACH,CAAC;IAED,WAAW;QACT,EAAE,CAAC,CAAC,CAAC,IAAI,CAAC,aAAa,CAAC,CAAC,CAAC;YACxB,IAAI,gBAAwB,CAAA;YAC5B,IAAI,MAA4B,CAAA;YAEhC,MAAM,WAAW,GAAG,CAAC,MAAsB;gBACzC,MAAM,GAAG,GAAG,OAAO,MAAM,KAAK,QAAQ;oBACpC,IAAI,KAAK,CAAC,oBAAoB,GAAG,MAAM,CAAC,GAAG,MAAM,CAAA;gBAEjD,OAAO,CAAC,KAAK,CAAC,YAAY,EAAE,GAAG,CAAC,CAAA;gBAChC,IAAI,CAAC,SAAS,CAAC,SAAS,CAAC,GAAG,CAAC,CAAA;gBAC7B,MAAM,CAAC,GAAG,CAAC,CAAA;gBACX,IAAI,CAAC,aAAa,GAAG,SAAS,CAAA;gBAE9B,YAAY,CAAC;oBACX,IAAI,MAAM,GAAG,GAAG,IAAI,GAAG,CAAC,KAAK,IAAI,EAAE,CAAA;oBAEnC,EAAE,CAAC,CAAC,gBAAgB,CAAC,CAAC,CAAC;wBACrB,MAAM,GAAG,8BAA8B,GAAG,gBAAgB,GAAG,OAAO,GAAG,MAAM,CAAA;oBAC/E,CAAC;oBAED,IAAI,CAAC,aAAa,CAAC,QAAQ,CAAC,8BAA8B,EAAE;wBAC1D,MAAM;wBACN,WAAW,EAAE,IAAI;qBAClB,CAAC,CAAA;gBACJ,CAAC,CAAC,CAAA;YACN,CAAC,CAAA;YAED,MAAM,CAAC,IAAI,CAAC,aAAa,GAAG,IAAI,OAAO,CAAe,CAAC,OAAO,EAAE,OAAO;gBACrE,MAAM,GAAG,OAAO,CAAA;gBAEhB,EAAE,CAAC,CAAC,MAAM,CAAC,qBAAqB,CAAC,CAAC,CAAC;oBACjC,OAAO,CAAC,GAAG,CAAC,UAAU,EAAE,IAAI,CAAC,YAAY,CAAC,CAAA;gBAC5C,CAAC;gBAED,MAAM,EAAE,GAAG,WAAW,CAAC,IAAI,CAAC,YAAY,EAAE,IAAI,CAAC,YAAY,CAAC,CAAA;gBAE5D,EAAE,CAAC,IAAI,CAAC,OAAO,EAAE,WAAW,CAAC,CAAA;gBAC7B,EAAE,CAAC,IAAI,CAAC,MAAM,EAAE,WAAW,CAAC,CAAA;gBAE5B,4CAA4C;gBAC5C,aAAa,CAAC,EAAE,CAAC,MAAM,CAAC,CAAC,EAAE,CAAC,MAAM,EAAE,IAAI,CAAC,SAAS,CAAC,CAAA;gBACnD,EAAE,CAAC,MAAM,CAAC,EAAE,CAAC,MAAM,EAAE,IAAI;oBACvB,OAAO,CAAC,IAAI,CAAC,kBAAkB,EAAE,gBAAgB,GAAG,IAAI,CAAC,QAAQ,EAAE,CAAC,CAAA;gBACtE,CAAC,CAAC,CAAA;gBAEF,mEAAmE;gBACnE,IAAI,CAAC,WAAW,CAAC,EAAE,EAAE,MAAM,EAAE,IAAI,EAAE,IAAI,CAAC,CAAC,IAAI,CAAC,GAAG,IAAI,OAAO,CAAC,EAAE,CAAC,EAAE,GAAG,IAAI,OAAO,CAAC,EAAE,CAAC,CAAC,CAAA;YACvF,CAAC,CAAC,CAAA;QAEJ,CAAC;QAAC,IAAI,CAAC,CAAC;YACN,MAAM,IAAI,KAAK,CAAC,2BAA2B,IAAI,CAAC,YAAY,EAAE,CAAC,CAAA;QACjE,CAAC;IACH,CAAC;CACF;AAxND,0DAwNC;AAED,qBAAqB,YAAoB,EAAE,YAAsB;IAC/D,EAAE,CAAC,CAAC,gBAAgB,CAAC,CAAC,CAAC;QACrB,MAAM,CAAC,IAAI,sBAAe,CAAC;YACzB,OAAO,EAAE,MAAM;YACf,IAAI,EAAE,CAAC,WAAW,EAAE,YAAY,CAAC,CAAC,MAAM,CAAC,YAAY,CAAC;SACvD,CAAC,CAAC,OAAc,CAAA;IACnB,CAAC;IAAC,IAAI,CAAC,CAAC;QACN,MAAM,CAAC,IAAI,0BAAmB,CAAC;YAC7B,OAAO,EAAE,YAAY;YACrB,IAAI,EAAE,YAAY;SACnB,CAAC,CAAC,OAAc,CAAA;IACnB,CAAC;AACH,CAAC;AAED,iBAAiB,GAAuC;IACtD,MAAM,CAAC,GAAG,CAAC,IAAI,KAAK,OAAO,CAAA;AAC7B,CAAC;AAED,oBAAoB,GAAuC;IACzD,MAAM,CAAC,GAAG,CAAC,IAAI,KAAK,UAAU,CAAA;AAChC,CAAC;AAED,uBAAuB,KAAe;IACpC,MAAM,CAAC,KAAK,CAAC,IAAI,CAAC,MAAM,EAAE,CAAC,CAAC,IAAI,CAAC,IAAI,aAAa,EAAE,CAAC,CAAA;AACvD,CAAC;AAED,sEAAsE;AACtE,mBAAoB,SAAQ,kBAAS;IACnC;QACE,KAAK,CAAC,EAAC,UAAU,EAAE,IAAI,EAAC,CAAC,CAAA;IAC3B,CAAC;IAED,UAAU,CAAC,GAAW,EAAE,QAAgB,EAAE,QAAkB;QAC1D,MAAM,IAAI,GAAG,GAAG,CAAC,QAAQ,EAAE,CAAA;QAE3B,IAAI,CAAC;YACH,EAAE,CAAC,CAAC,IAAI,CAAC,UAAU,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC;gBACzB,IAAI,CAAC,IAAI,CAAC,IAAI,CAAC,KAAK,CAAC,IAAI,CAAC,CAAC,CAAA;YAC7B,CAAC;YAAC,IAAI,CAAC,EAAE,CAAC,CAAC,CAAC,IAAI,CAAC,UAAU,CAAC,iBAAiB,CAAC,CAAC,CAAC,CAAC;gBAC/C,OAAO,CAAC,IAAI,CAAC,IAAI,CAAC,CAAA;YACpB,CAAC;QACH,CAAC;QAAC,KAAK,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC;YACf,OAAO,CAAC,KAAK,CAAC,2BAA2B,EAAE,IAAI,CAAC,CAAA;QAClD,CAAC;gBAAS,CAAC;YACT,QAAQ,CAAC,IAAI,CAAC,CAAA;QAChB,CAAC;IACH,CAAC;CACF"} \ No newline at end of file diff --git a/dist/client/clientResolver.js b/dist/client/clientResolver.js new file mode 100644 index 000000000..02202edce --- /dev/null +++ b/dist/client/clientResolver.js @@ -0,0 +1,78 @@ +"use strict"; +Object.defineProperty(exports, "__esModule", { value: true }); +const client_1 = require("./client"); +const events = require("events"); +const path = require("path"); +const resolve_1 = require("resolve"); +const defaultServer = { + serverPath: require.resolve("typescript/bin/tsserver"), + version: require("typescript").version +}; +/** + * ClientResolver takes care of finding the correct tsserver for a source file based on how a + * require("typescript") from the same source file would resolve. + */ +class ClientResolver extends events.EventEmitter { + constructor() { + super(...arguments); + this.clients = {}; + } + on(event, callback) { + return super.on(event, callback); + } + get(filePath) { + return resolveServer(filePath) + .catch(() => defaultServer) + .then(({ serverPath, version }) => { + if (this.clients[serverPath]) { + return this.clients[serverPath].client; + } + const entry = this.addClient(serverPath, new client_1.TypescriptServiceClient(serverPath, version)); + entry.client.startServer(); + entry.client.on("pendingRequestsChange", pending => { + entry.pending = pending; + this.emit("pendingRequestsChange"); + }); + const diagnosticHandler = (type, result) => { + const filePath = isConfDiagBody(result) ? result.configFile : result.file; + if (filePath) { + this.emit("diagnostics", { + type, + serverPath, + filePath, + diagnostics: result.diagnostics + }); + } + }; + entry.client.on("configFileDiag", diagnosticHandler.bind(this, "configFileDiag")); + entry.client.on("semanticDiag", diagnosticHandler.bind(this, "semanticDiag")); + entry.client.on("syntaxDiag", diagnosticHandler.bind(this, "syntaxDiag")); + return entry.client; + }); + } + addClient(serverPath, client) { + this.clients[serverPath] = { + client, + pending: [], + }; + return this.clients[serverPath]; + } +} +exports.ClientResolver = ClientResolver; +function resolveServer(sourcePath) { + const basedir = path.dirname(sourcePath); + return Promise.resolve().then(() => { + const resolvedPath = resolve_1.sync("typescript/bin/tsserver", { basedir }); + const packagePath = path.resolve(resolvedPath, "../../package.json"); + const version = require(packagePath).version; + return { + version, + serverPath: resolvedPath + }; + }); +} +exports.resolveServer = resolveServer; +function isConfDiagBody(body) { + return body && body.triggerFile && body.configFile; +} +//# sourceMappingURL=clientResolver.js.map \ No newline at end of file diff --git a/dist/client/clientResolver.js.map b/dist/client/clientResolver.js.map new file mode 100644 index 000000000..fba50e720 --- /dev/null +++ b/dist/client/clientResolver.js.map @@ -0,0 +1 @@ +{"version":3,"file":"clientResolver.js","sourceRoot":"","sources":["../../lib/client/clientResolver.ts"],"names":[],"mappings":";;AAAA,qCAA0D;AAC1D,iCAAgC;AAChC,6BAA4B;AAC5B,qCAA2C;AAiB3C,MAAM,aAAa,GAAW;IAC5B,UAAU,EAAE,OAAO,CAAC,OAAO,CAAC,yBAAyB,CAAC;IACtD,OAAO,EAAE,OAAO,CAAC,YAAY,CAAC,CAAC,OAAO;CACvC,CAAA;AAED;;;GAGG;AACH,oBAA4B,SAAQ,MAAM,CAAC,YAAY;IAAvD;;QAEE,YAAO,GAKH,EAAE,CAAA;IAuDR,CAAC;IAlDC,EAAE,CAAC,KAAa,EAAE,QAAkB;QAClC,MAAM,CAAC,KAAK,CAAC,EAAE,CAAC,KAAK,EAAE,QAAQ,CAAC,CAAA;IAClC,CAAC;IAED,GAAG,CAAC,QAAgB;QAClB,MAAM,CAAC,aAAa,CAAC,QAAQ,CAAC;aAC3B,KAAK,CAAC,MAAM,aAAa,CAAC;aAC1B,IAAI,CAAC,CAAC,EAAC,UAAU,EAAE,OAAO,EAAC;YAC1B,EAAE,CAAC,CAAC,IAAI,CAAC,OAAO,CAAC,UAAU,CAAC,CAAC,CAAC,CAAC;gBAC7B,MAAM,CAAC,IAAI,CAAC,OAAO,CAAC,UAAU,CAAC,CAAC,MAAM,CAAA;YACxC,CAAC;YAED,MAAM,KAAK,GAAG,IAAI,CAAC,SAAS,CAAC,UAAU,EAAE,IAAI,gCAAM,CAAC,UAAU,EAAE,OAAO,CAAC,CAAC,CAAA;YAEzE,KAAK,CAAC,MAAM,CAAC,WAAW,EAAE,CAAA;YAE1B,KAAK,CAAC,MAAM,CAAC,EAAE,CAAC,uBAAuB,EAAE,OAAO;gBAC9C,KAAK,CAAC,OAAO,GAAG,OAAO,CAAA;gBACvB,IAAI,CAAC,IAAI,CAAC,uBAAuB,CAAC,CAAA;YACpC,CAAC,CAAC,CAAA;YAEF,MAAM,iBAAiB,GAAG,CAAC,IAAY,EAAE,MAA2D;gBAClG,MAAM,QAAQ,GAAG,cAAc,CAAC,MAAM,CAAC,GAAG,MAAM,CAAC,UAAU,GAAG,MAAM,CAAC,IAAI,CAAA;gBAEzE,EAAE,CAAC,CAAC,QAAQ,CAAC,CAAC,CAAC;oBACb,IAAI,CAAC,IAAI,CAAC,aAAa,EAAE;wBACvB,IAAI;wBACJ,UAAU;wBACV,QAAQ;wBACR,WAAW,EAAE,MAAM,CAAC,WAAW;qBAChC,CAAC,CAAA;gBACJ,CAAC;YACH,CAAC,CAAA;YAED,KAAK,CAAC,MAAM,CAAC,EAAE,CAAC,gBAAgB,EAAE,iBAAiB,CAAC,IAAI,CAAC,IAAI,EAAE,gBAAgB,CAAC,CAAC,CAAA;YACjF,KAAK,CAAC,MAAM,CAAC,EAAE,CAAC,cAAc,EAAE,iBAAiB,CAAC,IAAI,CAAC,IAAI,EAAE,cAAc,CAAC,CAAC,CAAA;YAC7E,KAAK,CAAC,MAAM,CAAC,EAAE,CAAC,YAAY,EAAE,iBAAiB,CAAC,IAAI,CAAC,IAAI,EAAE,YAAY,CAAC,CAAC,CAAA;YAEzE,MAAM,CAAC,KAAK,CAAC,MAAM,CAAA;QACrB,CAAC,CAAC,CAAA;IACN,CAAC;IAED,SAAS,CAAC,UAAkB,EAAE,MAAc;QAC1C,IAAI,CAAC,OAAO,CAAC,UAAU,CAAC,GAAG;YACzB,MAAM;YACN,OAAO,EAAE,EAAE;SACZ,CAAA;QAED,MAAM,CAAC,IAAI,CAAC,OAAO,CAAC,UAAU,CAAC,CAAA;IACjC,CAAC;CACF;AA9DD,wCA8DC;AAED,uBAA8B,UAAkB;IAC9C,MAAM,OAAO,GAAG,IAAI,CAAC,OAAO,CAAC,UAAU,CAAC,CAAA;IAExC,MAAM,CAAC,OAAO,CAAC,OAAO,EAAE,CAAC,IAAI,CAAC;QAC5B,MAAM,YAAY,GAAG,cAAW,CAAC,yBAAyB,EAAE,EAAC,OAAO,EAAC,CAAC,CAAA;QACtE,MAAM,WAAW,GAAG,IAAI,CAAC,OAAO,CAAC,YAAY,EAAE,oBAAoB,CAAC,CAAA;QACpE,MAAM,OAAO,GAAG,OAAO,CAAC,WAAW,CAAC,CAAC,OAAO,CAAA;QAE5C,MAAM,CAAC;YACL,OAAO;YACP,UAAU,EAAE,YAAY;SACzB,CAAA;IACH,CAAC,CAAC,CAAA;AACJ,CAAC;AAbD,sCAaC;AAED,wBAAwB,IAAS;IAC/B,MAAM,CAAC,IAAI,IAAI,IAAI,CAAC,WAAW,IAAI,IAAI,CAAC,UAAU,CAAA;AACpD,CAAC"} \ No newline at end of file diff --git a/dist/hyperclickProvider.js b/dist/hyperclickProvider.js deleted file mode 100644 index 8cc4b58e2..000000000 --- a/dist/hyperclickProvider.js +++ /dev/null @@ -1,31 +0,0 @@ -"use strict"; -var parent = require("./worker/parent"); -var atomUtils = require("./main/atom/atomUtils"); -var immutable_1 = require("immutable"); -var TS_GRAMMARS = immutable_1.Set(["source.ts", "source.tsx"]); -exports.providerName = "typescript-hyperclick-provider"; -exports.wordRegExp = /([A-Za-z0-9_])+|['"`](\\.|[^'"`\\\\])*['"`]/g; -function getSuggestionForWord(textEditor, text, range) { - if (!TS_GRAMMARS.has(textEditor.getGrammar().scopeName)) { - return null; - } - return { - range: range, - callback: function () { - var filePathPosition = { - filePath: textEditor.getPath(), - position: atomUtils.getEditorPositionForBufferPosition(textEditor, range.start) - }; - parent.getDefinitionsAtPosition(filePathPosition).then(function (res) { - if (res.definitions.length > 0) { - var definition = res.definitions[0]; - atom.workspace.open(definition.filePath, { - initialLine: definition.position.line, - initialColumn: definition.position.col - }); - } - }); - } - }; -} -exports.getSuggestionForWord = getSuggestionForWord; diff --git a/dist/linter.js b/dist/linter.js deleted file mode 100644 index 983923adc..000000000 --- a/dist/linter.js +++ /dev/null @@ -1,30 +0,0 @@ -"use strict"; -var parent = require("./worker/parent"); -var fs = require("fs"); -var atom_1 = require("atom"); -exports.provider = { - name: 'TS', - grammarScopes: ['source.ts', 'source.tsx'], - scope: 'file', - lintOnFly: true, - lint: function (textEditor) { - if (!textEditor.buffer.file - || !textEditor.buffer.file.path - || !fs.existsSync(textEditor.buffer.file.path)) - return Promise.resolve([]); - var filePath = textEditor.buffer.file.path; - return parent.errorsForFile({ filePath: filePath }) - .then(function (resp) { - var linterErrors = resp.errors.map(function (err) { return ({ - type: "Error", - filePath: filePath, - text: err.message, - range: new atom_1.Range([err.startPos.line, err.startPos.col], [err.endPos.line, err.endPos.col]), - }); }); - return linterErrors; - }) - .catch(function (error) { - return []; - }); - } -}; diff --git a/dist/main/atom/atomConfig.js b/dist/main/atom/atomConfig.js deleted file mode 100644 index f8b9811fb..000000000 --- a/dist/main/atom/atomConfig.js +++ /dev/null @@ -1,74 +0,0 @@ -"use strict"; -var utils_1 = require("../lang/utils"); -var packageName = 'atom-typescript'; -function getConfig(nameLambda) { - return atom.config.get(packageName + '.' + utils_1.getName(nameLambda)); -} -function setConfig(nameLambda, value) { - return atom.config.set(packageName + '.' + utils_1.getName(nameLambda), value); -} -var Config = (function () { - function Config() { - this.schema = { - debugAtomTs: { - title: 'Debug: Atom-TypeScript. Please do not use.', - type: 'boolean', - default: false - }, - preferredQuoteCharacter: { - title: 'Preferred quote character', - type: 'string', - default: 'none' - }, - typescriptServices: { - title: 'Full path (including file name) to a custom `typescriptServices.js`', - type: 'string', - default: '' - }, - showSemanticView: { - title: 'Show semantic view', - type: 'boolean', - default: false - } - }; - } - Object.defineProperty(Config.prototype, "debugAtomTs", { - get: function () { - var _this = this; - return getConfig(function () { return _this.schema.debugAtomTs; }); - }, - enumerable: true, - configurable: true - }); - Object.defineProperty(Config.prototype, "preferredQuoteCharacter", { - get: function () { - var _this = this; - return getConfig(function () { return _this.schema.preferredQuoteCharacter; }); - }, - enumerable: true, - configurable: true - }); - Object.defineProperty(Config.prototype, "typescriptServices", { - get: function () { - var _this = this; - return getConfig(function () { return _this.schema.typescriptServices; }); - }, - enumerable: true, - configurable: true - }); - Object.defineProperty(Config.prototype, "showSemanticView", { - get: function () { - var _this = this; - return getConfig(function () { return _this.schema.showSemanticView; }); - }, - set: function (value) { - var _this = this; - setConfig(function () { return _this.schema.showSemanticView; }, value); - }, - enumerable: true, - configurable: true - }); - return Config; -}()); -var config = new Config(); -module.exports = config; diff --git a/dist/main/atom/autoCompleteProvider.js b/dist/main/atom/autoCompleteProvider.js index a69fdb69c..c4067f981 100644 --- a/dist/main/atom/autoCompleteProvider.js +++ b/dist/main/atom/autoCompleteProvider.js @@ -1,105 +1,150 @@ "use strict"; -var parent = require("../../worker/parent"); -var fs = require("fs"); -var atomUtils = require("./atomUtils"); -var fuzzaldrin = require('fuzzaldrin'); -var CSON = require("season"); -var explicitlyTriggered = false; -function triggerAutocompletePlus() { - atom.commands.dispatch(atom.views.getView(atom.workspace.getActiveTextEditor()), 'autocomplete-plus:activate'); - explicitlyTriggered = true; -} -exports.triggerAutocompletePlus = triggerAutocompletePlus; -function getModuleAutocompleteType(scopes) { - function has(match) { - return scopes.some(function (scope) { return scope.indexOf(match) !== -1; }); +Object.defineProperty(exports, "__esModule", { value: true }); +const tslib_1 = require("tslib"); +const utils_1 = require("./utils"); +const Atom = require("atom"); +const fuzzaldrin = require("fuzzaldrin"); +const importPathScopes = ["meta.import", "meta.import-equals", "triple-slash-directive"]; +class AutocompleteProvider { + constructor(clientResolver, opts) { + this.selector = ".source.ts, .source.tsx"; + this.disableForSelector = ".comment"; + this.inclusionPriority = 3; + this.suggestionPriority = 3; + this.excludeLowerPriority = false; + this.clientResolver = clientResolver; + this.opts = opts; } - var isString = has('string.quoted'); - return { - isReference: has('reference.path.string.quoted') || has('amd.path.string.quoted'), - isRequire: has('meta.import-equals.external') && isString, - isImport: has('meta.import') && isString - }; -} -exports.provider = { - selector: '.source.ts, .source.tsx', - inclusionPriority: 3, - suggestionPriority: 3, - excludeLowerPriority: false, - getSuggestions: function (options) { - var filePath = options.editor.getPath(); - if (!filePath) - return Promise.resolve([]); - if (!fs.existsSync(filePath)) - return Promise.resolve([]); - var _a = getModuleAutocompleteType(options.scopeDescriptor.scopes), isReference = _a.isReference, isRequire = _a.isRequire, isImport = _a.isImport; - if (isReference || isRequire || isImport) { - return parent.getRelativePathsInProject({ filePath: filePath, prefix: options.prefix, includeExternalModules: isReference }) - .then(function (resp) { - var range = options.editor.bufferRangeForScopeAtCursor(".string.quoted"); - var cursor = options.editor.getCursorBufferPosition(); - if (!range || cursor.column !== range.end.column - 1) { + // Try to reuse the last completions we got from tsserver if they're for the same position. + getSuggestionsWithCache(prefix, location, activatedManually) { + return tslib_1.__awaiter(this, void 0, void 0, function* () { + if (this.lastSuggestions && !activatedManually) { + const lastLoc = this.lastSuggestions.location; + const lastCol = getNormalizedCol(this.lastSuggestions.prefix, lastLoc.offset); + const thisCol = getNormalizedCol(prefix, location.offset); + if (lastLoc.file === location.file && lastLoc.line == location.line && lastCol === thisCol) { + if (this.lastSuggestions.suggestions.length !== 0) { + return this.lastSuggestions.suggestions; + } + } + } + const client = yield this.clientResolver.get(location.file); + const completions = yield client.executeCompletions(Object.assign({ prefix }, location)); + const suggestions = completions.body.map(entry => ({ + text: entry.name, + leftLabel: entry.kind, + type: utils_1.kindToType(entry.kind), + })); + this.lastSuggestions = { + client, + location, + prefix, + suggestions, + }; + return suggestions; + }); + } + getSuggestions(opts) { + return tslib_1.__awaiter(this, void 0, void 0, function* () { + const location = getLocationQuery(opts); + const { prefix } = opts; + if (!location.file) { + return []; + } + // Don't show autocomplete if the previous character was a non word character except "." + const lastChar = getLastNonWhitespaceChar(opts.editor.buffer, opts.bufferPosition); + if (lastChar && !opts.activatedManually) { + if (/\W/i.test(lastChar) && lastChar !== ".") { return []; } - var content = options.editor.getTextInBufferRange(range).replace(/^['"]|['"]$/g, ""); - return resp.files.map(function (file) { - var relativePath = file.relativePath; - var suggestionText = relativePath; - var suggestion = { - text: suggestionText, - replacementPrefix: content, - rightLabelHTML: '' + file.name + '', - type: 'import' - }; - return suggestion; - }); - }); - } - else { - if (explicitlyTriggered) { - explicitlyTriggered = false; } - else { - var prefix = options.prefix.trim(); - if (prefix === '' || prefix === ';' || prefix === '{') { - return Promise.resolve([]); + // Don't show autocomplete if we're in a string.template and not in a template expression + if (containsScope(opts.scopeDescriptor.scopes, "string.template.") + && !containsScope(opts.scopeDescriptor.scopes, "template.expression.")) { + return []; + } + // Don't show autocomplete if we're in a string and it's not an import path + if (containsScope(opts.scopeDescriptor.scopes, "string.quoted.")) { + if (!importPathScopes.some(scope => containsScope(opts.scopeDescriptor.scopes, scope))) { + return []; } } - var position = atomUtils.getEditorPositionForBufferPosition(options.editor, options.bufferPosition); - var promisedSuggestions = parent.getCompletionsAtPosition({ - filePath: filePath, - position: position, - prefix: options.prefix, - }) - .then(function (resp) { - var completionList = resp.completions; - var suggestions = completionList.map(function (c) { - if (c.snippet) { - return { - snippet: c.snippet, - replacementPrefix: '', - rightLabel: 'signature', - type: 'snippet', - }; - } - else { - var prefix = options.prefix; - if (c.name && c.name.startsWith('$')) { - prefix = "$" + prefix; - } - return { - text: c.name, - replacementPrefix: resp.endsInPunctuation ? '' : prefix.trim(), - rightLabel: c.display, - leftLabel: c.kind, - type: atomUtils.kindToType(c.kind), - description: c.comment, - }; + // Flush any pending changes for this buffer to get up to date completions + const { buffer } = yield this.opts.getTypescriptBuffer(location.file); + yield buffer.flush(); + try { + var suggestions = yield this.getSuggestionsWithCache(prefix, location, opts.activatedManually); + } + catch (error) { + return []; + } + const alphaPrefix = prefix.replace(/\W/g, ""); + if (alphaPrefix !== "") { + suggestions = fuzzaldrin.filter(suggestions, alphaPrefix, { key: "text" }); + } + // Get additional details for the first few suggestions + yield this.getAdditionalDetails(suggestions.slice(0, 10), location); + const trimmed = prefix.trim(); + return suggestions.map(suggestion => (Object.assign({ replacementPrefix: getReplacementPrefix(prefix, trimmed, suggestion.text) }, suggestion))); + }); + } + getAdditionalDetails(suggestions, location) { + return tslib_1.__awaiter(this, void 0, void 0, function* () { + if (suggestions.some(s => !s.details)) { + const details = yield this.lastSuggestions.client.executeCompletionDetails(Object.assign({ entryNames: suggestions.map(s => s.text) }, location)); + details.body.forEach((detail, i) => { + const suggestion = suggestions[i]; + suggestion.details = detail; + suggestion.rightLabel = detail.displayParts.map(d => d.text).join(""); + if (detail.documentation) { + suggestion.description = detail.documentation.map(d => d.text).join(" "); } }); - return suggestions; - }); - return promisedSuggestions; + } + }); + } +} +exports.AutocompleteProvider = AutocompleteProvider; +// Decide what needs to be replaced in the editor buffer when inserting the completion +function getReplacementPrefix(prefix, trimmed, replacement) { + if (trimmed === "." || trimmed === "{" || prefix === " ") { + return ""; + } + else if (replacement.startsWith("$")) { + return "$" + prefix; + } + else { + return prefix; + } +} +// When the user types each character in ".hello", we want to normalize the column such that it's +// the same for every invocation of the getSuggestions. In this case, it would be right after "." +function getNormalizedCol(prefix, col) { + const length = prefix === "." ? 0 : prefix.length; + return col - length; +} +function getLocationQuery(opts) { + return { + file: opts.editor.getPath(), + line: opts.bufferPosition.row + 1, + offset: opts.bufferPosition.column + 1 + }; +} +function getLastNonWhitespaceChar(buffer, pos) { + let lastChar = undefined; + const range = new Atom.Range([0, 0], pos); + buffer.backwardsScanInRange(/\S/, range, ({ matchText, stop }) => { + lastChar = matchText; + stop(); + }); + return lastChar; +} +function containsScope(scopes, matchScope) { + for (const scope of scopes) { + if (scope.includes(matchScope)) { + return true; } - }, -}; + } + return false; +} +//# sourceMappingURL=autoCompleteProvider.js.map \ No newline at end of file diff --git a/dist/main/atom/autoCompleteProvider.js.map b/dist/main/atom/autoCompleteProvider.js.map new file mode 100644 index 000000000..c2dc51d2a --- /dev/null +++ b/dist/main/atom/autoCompleteProvider.js.map @@ -0,0 +1 @@ +{"version":3,"file":"autoCompleteProvider.js","sourceRoot":"","sources":["../../../lib/main/atom/autoCompleteProvider.ts"],"names":[],"mappings":";;;AAEA,mCAAqD;AAIrD,6BAA4B;AAC5B,yCAAwC;AAExC,MAAM,gBAAgB,GAAG,CAAC,aAAa,EAAE,oBAAoB,EAAE,wBAAwB,CAAC,CAAA;AAaxF;IA0BE,YAAY,cAA8B,EAAE,IAAa;QAzBzD,aAAQ,GAAG,yBAAyB,CAAA;QAEpC,uBAAkB,GAAG,UAAU,CAAA;QAE/B,sBAAiB,GAAG,CAAC,CAAA;QACrB,uBAAkB,GAAG,CAAC,CAAA;QACtB,yBAAoB,GAAG,KAAK,CAAA;QAoB1B,IAAI,CAAC,cAAc,GAAG,cAAc,CAAA;QACpC,IAAI,CAAC,IAAI,GAAG,IAAI,CAAA;IAClB,CAAC;IAED,2FAA2F;IACrF,uBAAuB,CAC3B,MAAc,EACd,QAA2B,EAC3B,iBAA0B;;YAE1B,EAAE,CAAC,CAAC,IAAI,CAAC,eAAe,IAAI,CAAC,iBAAiB,CAAC,CAAC,CAAC;gBAC/C,MAAM,OAAO,GAAG,IAAI,CAAC,eAAe,CAAC,QAAQ,CAAA;gBAC7C,MAAM,OAAO,GAAG,gBAAgB,CAAC,IAAI,CAAC,eAAe,CAAC,MAAM,EAAE,OAAO,CAAC,MAAM,CAAC,CAAA;gBAC7E,MAAM,OAAO,GAAG,gBAAgB,CAAC,MAAM,EAAE,QAAQ,CAAC,MAAM,CAAC,CAAA;gBAEzD,EAAE,CAAC,CAAC,OAAO,CAAC,IAAI,KAAK,QAAQ,CAAC,IAAI,IAAI,OAAO,CAAC,IAAI,IAAI,QAAQ,CAAC,IAAI,IAAI,OAAO,KAAK,OAAO,CAAC,CAAC,CAAC;oBAC3F,EAAE,CAAC,CAAC,IAAI,CAAC,eAAe,CAAC,WAAW,CAAC,MAAM,KAAK,CAAC,CAAC,CAAC,CAAC;wBAClD,MAAM,CAAC,IAAI,CAAC,eAAe,CAAC,WAAW,CAAA;oBACzC,CAAC;gBACH,CAAC;YACH,CAAC;YAED,MAAM,MAAM,GAAG,MAAM,IAAI,CAAC,cAAc,CAAC,GAAG,CAAC,QAAQ,CAAC,IAAI,CAAC,CAAA;YAC3D,MAAM,WAAW,GAAG,MAAM,MAAM,CAAC,kBAAkB,iBAAE,MAAM,IAAK,QAAQ,EAAE,CAAA;YAE1E,MAAM,WAAW,GAAG,WAAW,CAAC,IAAK,CAAC,GAAG,CAAC,KAAK,IAAI,CAAC;gBAClD,IAAI,EAAE,KAAK,CAAC,IAAI;gBAChB,SAAS,EAAE,KAAK,CAAC,IAAI;gBACrB,IAAI,EAAE,kBAAU,CAAC,KAAK,CAAC,IAAI,CAAC;aAC7B,CAAC,CAAC,CAAA;YAEH,IAAI,CAAC,eAAe,GAAG;gBACrB,MAAM;gBACN,QAAQ;gBACR,MAAM;gBACN,WAAW;aACZ,CAAA;YAED,MAAM,CAAC,WAAW,CAAA;QACpB,CAAC;KAAA;IAEK,cAAc,CAAC,IAAoB;;YACvC,MAAM,QAAQ,GAAG,gBAAgB,CAAC,IAAI,CAAC,CAAA;YACvC,MAAM,EAAC,MAAM,EAAC,GAAG,IAAI,CAAA;YAErB,EAAE,CAAC,CAAC,CAAC,QAAQ,CAAC,IAAI,CAAC,CAAC,CAAC;gBACnB,MAAM,CAAC,EAAE,CAAA;YACX,CAAC;YAED,wFAAwF;YACxF,MAAM,QAAQ,GAAG,wBAAwB,CAAC,IAAI,CAAC,MAAM,CAAC,MAAM,EAAE,IAAI,CAAC,cAAc,CAAC,CAAA;YAClF,EAAE,CAAC,CAAC,QAAQ,IAAI,CAAC,IAAI,CAAC,iBAAiB,CAAC,CAAC,CAAC;gBACxC,EAAE,CAAC,CAAC,KAAK,CAAC,IAAI,CAAC,QAAQ,CAAC,IAAI,QAAQ,KAAK,GAAG,CAAC,CAAC,CAAC;oBAC7C,MAAM,CAAC,EAAE,CAAA;gBACX,CAAC;YACH,CAAC;YAED,yFAAyF;YACzF,EAAE,CAAC,CAAC,aAAa,CAAC,IAAI,CAAC,eAAe,CAAC,MAAM,EAAE,kBAAkB,CAAC;mBAC7D,CAAC,aAAa,CAAC,IAAI,CAAC,eAAe,CAAC,MAAM,EAAE,sBAAsB,CAAC,CAAC,CAAC,CAAC;gBACvE,MAAM,CAAC,EAAE,CAAA;YACb,CAAC;YAED,2EAA2E;YAC3E,EAAE,CAAC,CAAC,aAAa,CAAC,IAAI,CAAC,eAAe,CAAC,MAAM,EAAE,gBAAgB,CAAC,CAAC,CAAC,CAAC;gBACjE,EAAE,CAAC,CAAC,CAAC,gBAAgB,CAAC,IAAI,CAAC,KAAK,IAAI,aAAa,CAAC,IAAI,CAAC,eAAe,CAAC,MAAM,EAAE,KAAK,CAAC,CAAC,CAAC,CAAC,CAAC;oBACvF,MAAM,CAAC,EAAE,CAAA;gBACX,CAAC;YACH,CAAC;YAED,0EAA0E;YAC1E,MAAM,EAAC,MAAM,EAAC,GAAG,MAAM,IAAI,CAAC,IAAI,CAAC,mBAAmB,CAAC,QAAQ,CAAC,IAAI,CAAC,CAAA;YACnE,MAAM,MAAM,CAAC,KAAK,EAAE,CAAA;YAEpB,IAAI,CAAC;gBACH,IAAI,WAAW,GAAG,MAAM,IAAI,CAAC,uBAAuB,CAAC,MAAM,EAAE,QAAQ,EAAE,IAAI,CAAC,iBAAiB,CAAC,CAAA;YAChG,CAAC;YAAC,KAAK,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC;gBACf,MAAM,CAAC,EAAE,CAAA;YACX,CAAC;YAED,MAAM,WAAW,GAAG,MAAM,CAAC,OAAO,CAAC,KAAK,EAAE,EAAE,CAAC,CAAA;YAC7C,EAAE,CAAC,CAAC,WAAW,KAAK,EAAE,CAAC,CAAC,CAAC;gBACvB,WAAW,GAAG,UAAU,CAAC,MAAM,CAAC,WAAW,EAAE,WAAW,EAAE,EAAC,GAAG,EAAE,MAAM,EAAC,CAAC,CAAA;YAC1E,CAAC;YAED,uDAAuD;YACvD,MAAM,IAAI,CAAC,oBAAoB,CAAC,WAAW,CAAC,KAAK,CAAC,CAAC,EAAE,EAAE,CAAC,EAAE,QAAQ,CAAC,CAAA;YAEnE,MAAM,OAAO,GAAG,MAAM,CAAC,IAAI,EAAE,CAAA;YAE7B,MAAM,CAAC,WAAW,CAAC,GAAG,CAAC,UAAU,IAAI,iBACnC,iBAAiB,EAAE,oBAAoB,CAAC,MAAM,EAAE,OAAO,EAAE,UAAU,CAAC,IAAK,CAAC,IACvE,UAAU,EACb,CAAC,CAAA;QACL,CAAC;KAAA;IAEK,oBAAoB,CAAC,WAAoC,EAAE,QAA2B;;YAC1F,EAAE,CAAC,CAAC,WAAW,CAAC,IAAI,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,OAAO,CAAC,CAAC,CAAC,CAAC;gBACtC,MAAM,OAAO,GAAG,MAAM,IAAI,CAAC,eAAe,CAAC,MAAM,CAAC,wBAAwB,iBACxE,UAAU,EAAE,WAAW,CAAC,GAAG,CAAC,CAAC,IAAI,CAAC,CAAC,IAAK,CAAC,IACtC,QAAQ,EACX,CAAA;gBAEF,OAAO,CAAC,IAAK,CAAC,OAAO,CAAC,CAAC,MAAM,EAAE,CAAC;oBAC9B,MAAM,UAAU,GAAG,WAAW,CAAC,CAAC,CAAC,CAAA;oBAEjC,UAAU,CAAC,OAAO,GAAG,MAAM,CAAA;oBAC3B,UAAU,CAAC,UAAU,GAAG,MAAM,CAAC,YAAY,CAAC,GAAG,CAAC,CAAC,IAAI,CAAC,CAAC,IAAI,CAAC,CAAC,IAAI,CAAC,EAAE,CAAC,CAAA;oBAErE,EAAE,CAAC,CAAC,MAAM,CAAC,aAAa,CAAC,CAAC,CAAC;wBACzB,UAAU,CAAC,WAAW,GAAG,MAAM,CAAC,aAAa,CAAC,GAAG,CAAC,CAAC,IAAI,CAAC,CAAC,IAAI,CAAC,CAAC,IAAI,CAAC,GAAG,CAAC,CAAA;oBAC1E,CAAC;gBACH,CAAC,CAAC,CAAA;YACJ,CAAC;QACH,CAAC;KAAA;CACF;AA9ID,oDA8IC;AAED,sFAAsF;AACtF,8BAA8B,MAAc,EAAE,OAAe,EAAE,WAAmB;IAChF,EAAE,CAAC,CAAC,OAAO,KAAK,GAAG,IAAI,OAAO,KAAK,GAAG,IAAI,MAAM,KAAK,GAAG,CAAC,CAAC,CAAC;QACzD,MAAM,CAAC,EAAE,CAAA;IACX,CAAC;IAAC,IAAI,CAAC,EAAE,CAAC,CAAC,WAAW,CAAC,UAAU,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC;QACvC,MAAM,CAAC,GAAG,GAAG,MAAM,CAAA;IACrB,CAAC;IAAC,IAAI,CAAC,CAAC;QACN,MAAM,CAAC,MAAM,CAAA;IACf,CAAC;AACH,CAAC;AAED,iGAAiG;AACjG,iGAAiG;AACjG,0BAA0B,MAAc,EAAE,GAAW;IACnD,MAAM,MAAM,GAAG,MAAM,KAAK,GAAG,GAAG,CAAC,GAAG,MAAM,CAAC,MAAM,CAAA;IACjD,MAAM,CAAC,GAAG,GAAG,MAAM,CAAA;AACrB,CAAC;AAED,0BAA0B,IAAoB;IAC5C,MAAM,CAAC;QACL,IAAI,EAAE,IAAI,CAAC,MAAM,CAAC,OAAO,EAAE;QAC3B,IAAI,EAAE,IAAI,CAAC,cAAc,CAAC,GAAG,GAAC,CAAC;QAC/B,MAAM,EAAE,IAAI,CAAC,cAAc,CAAC,MAAM,GAAC,CAAC;KACrC,CAAA;AACH,CAAC;AAED,kCAAkC,MAA8B,EAAE,GAAsB;IACtF,IAAI,QAAQ,GAAuB,SAAS,CAAA;IAC5C,MAAM,KAAK,GAAG,IAAI,IAAI,CAAC,KAAK,CAAC,CAAC,CAAC,EAAC,CAAC,CAAC,EAAE,GAAG,CAAC,CAAA;IACxC,MAAM,CAAC,oBAAoB,CAAC,IAAI,EAAE,KAAK,EAAE,CAAC,EAAC,SAAS,EAAE,IAAI,EAAwC;QAC9F,QAAQ,GAAG,SAAS,CAAA;QACpB,IAAI,EAAE,CAAA;IACR,CAAC,CAAC,CAAA;IACJ,MAAM,CAAC,QAAQ,CAAA;AACjB,CAAC;AAED,uBAAuB,MAAgB,EAAE,UAAkB;IACzD,GAAG,CAAC,CAAC,MAAM,KAAK,IAAI,MAAM,CAAC,CAAC,CAAC;QAC3B,EAAE,CAAC,CAAC,KAAK,CAAC,QAAQ,CAAC,UAAU,CAAC,CAAC,CAAC,CAAC;YAC/B,MAAM,CAAC,IAAI,CAAA;QACb,CAAC;IACH,CAAC;IAED,MAAM,CAAC,KAAK,CAAA;AACd,CAAC"} \ No newline at end of file diff --git a/dist/main/atom/buildView.js b/dist/main/atom/buildView.js deleted file mode 100644 index 07fccd1eb..000000000 --- a/dist/main/atom/buildView.js +++ /dev/null @@ -1,47 +0,0 @@ -"use strict"; -var mainPanelView = require("./views/mainPanelView"); -var lineMessageView = require("./views/lineMessageView"); -var gotoHistory = require("./gotoHistory"); -function getTitle(errorCount) { - var title = ' TypeScript Build'; - if (errorCount > 0) { - title = title + (" (\n " + errorCount + " \n error" + (errorCount === 1 ? "" : "s") + " \n )"); - } - return title; -} -function setBuildOutput(buildOutput) { - mainPanelView.panelView.clearBuild(); - if (buildOutput.counts.errors) { - mainPanelView.panelView.setBuildPanelCount(buildOutput.counts.errors); - } - else { - mainPanelView.panelView.setBuildPanelCount(0); - } - gotoHistory.buildOutput.members = []; - buildOutput.outputs.forEach(function (output) { - if (output.success) { - return; - } - output.errors.forEach(function (error) { - mainPanelView.panelView.addBuild(new lineMessageView.LineMessageView({ - goToLine: function (filePath, line, col) { return gotoHistory.gotoLine(filePath, line, col, gotoHistory.buildOutput); }, - message: error.message, - line: error.startPos.line + 1, - col: error.startPos.col, - file: error.filePath, - preview: error.preview - })); - gotoHistory.buildOutput.members.push({ filePath: error.filePath, line: error.startPos.line + 1, col: error.startPos.col }); - }); - }); - if (!buildOutput.counts.errors) { - atom.notifications.addSuccess("Build success"); - } - else if (buildOutput.counts.emitErrors) { - atom.notifications.addError("Emits errors: " + buildOutput.counts.emitErrors + " files."); - } - else { - atom.notifications.addWarning('Compile failed but emit succeeded'); - } -} -exports.setBuildOutput = setBuildOutput; diff --git a/dist/main/atom/commands/build.js b/dist/main/atom/commands/build.js new file mode 100644 index 000000000..eb3a6489a --- /dev/null +++ b/dist/main/atom/commands/build.js @@ -0,0 +1,47 @@ +"use strict"; +Object.defineProperty(exports, "__esModule", { value: true }); +const tslib_1 = require("tslib"); +const registry_1 = require("./registry"); +const utils_1 = require("../utils"); +registry_1.commands.set("typescript:build", deps => { + return (e) => tslib_1.__awaiter(this, void 0, void 0, function* () { + if (!utils_1.commandForTypeScript(e)) { + return; + } + const { file } = utils_1.getFilePathPosition(); + const client = yield deps.getClient(file); + const projectInfo = yield client.executeProjectInfo({ + file, + needFileNameList: true + }); + const files = new Set(projectInfo.body.fileNames); + const max = files.size; + const promises = [...files.values()].map(file => _finally(client.executeCompileOnSaveEmitFile({ file, forced: true }), () => { + files.delete(file); + updateStatus(); + })); + Promise.all(promises).then(results => { + if (results.some(result => result.body === false)) { + throw new Error("Emit failed"); + } + deps.statusPanel.setBuildStatus({ success: true }); + }).catch(() => { + deps.statusPanel.setBuildStatus({ success: false }); + }); + deps.statusPanel.setBuildStatus(undefined); + deps.statusPanel.setProgress({ max, value: 0 }); + function updateStatus() { + if (files.size === 0) { + deps.statusPanel.setProgress(undefined); + } + else { + deps.statusPanel.setProgress({ max, value: max - files.size }); + } + } + }); +}); +function _finally(promise, callback) { + promise.then(callback, callback); + return promise; +} +//# sourceMappingURL=build.js.map \ No newline at end of file diff --git a/dist/main/atom/commands/build.js.map b/dist/main/atom/commands/build.js.map new file mode 100644 index 000000000..2eeec5dcb --- /dev/null +++ b/dist/main/atom/commands/build.js.map @@ -0,0 +1 @@ +{"version":3,"file":"build.js","sourceRoot":"","sources":["../../../../lib/main/atom/commands/build.ts"],"names":[],"mappings":";;;AAAA,yCAAmC;AACnC,oCAAkE;AAElE,mBAAQ,CAAC,GAAG,CAAC,kBAAkB,EAAE,IAAI;IACnC,MAAM,CAAC,CAAM,CAAC;QACZ,EAAE,CAAC,CAAC,CAAC,4BAAoB,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC;YAC7B,MAAM,CAAA;QACR,CAAC;QAED,MAAM,EAAC,IAAI,EAAC,GAAG,2BAAmB,EAAE,CAAA;QACpC,MAAM,MAAM,GAAG,MAAM,IAAI,CAAC,SAAS,CAAC,IAAI,CAAC,CAAA;QAEzC,MAAM,WAAW,GAAG,MAAM,MAAM,CAAC,kBAAkB,CAAC;YAClD,IAAI;YACJ,gBAAgB,EAAE,IAAI;SACvB,CAAC,CAAA;QAEF,MAAM,KAAK,GAAG,IAAI,GAAG,CAAC,WAAW,CAAC,IAAK,CAAC,SAAS,CAAC,CAAA;QAClD,MAAM,GAAG,GAAG,KAAK,CAAC,IAAI,CAAA;QACtB,MAAM,QAAQ,GAAG,CAAC,GAAG,KAAK,CAAC,MAAM,EAAE,CAAC,CAAC,GAAG,CAAC,IAAI,IAC3C,QAAQ,CAAC,MAAM,CAAC,4BAA4B,CAAC,EAAC,IAAI,EAAE,MAAM,EAAE,IAAI,EAAC,CAAC,EAAE;YAClE,KAAK,CAAC,MAAM,CAAC,IAAI,CAAC,CAAA;YAClB,YAAY,EAAE,CAAA;QAChB,CAAC,CAAC,CACH,CAAA;QAED,OAAO,CAAC,GAAG,CAAC,QAAQ,CAAC,CAAC,IAAI,CAAC,OAAO;YAChC,EAAE,CAAC,CAAC,OAAO,CAAC,IAAI,CAAC,MAAM,IAAI,MAAM,CAAC,IAAI,KAAK,KAAK,CAAC,CAAC,CAAC,CAAC;gBAClD,MAAM,IAAI,KAAK,CAAC,aAAa,CAAC,CAAA;YAChC,CAAC;YAED,IAAI,CAAC,WAAW,CAAC,cAAc,CAAC,EAAC,OAAO,EAAE,IAAI,EAAC,CAAC,CAAA;QAClD,CAAC,CAAC,CAAC,KAAK,CAAC;YACP,IAAI,CAAC,WAAW,CAAC,cAAc,CAAC,EAAC,OAAO,EAAE,KAAK,EAAC,CAAC,CAAA;QACnD,CAAC,CAAC,CAAA;QAEF,IAAI,CAAC,WAAW,CAAC,cAAc,CAAC,SAAS,CAAC,CAAA;QAC1C,IAAI,CAAC,WAAW,CAAC,WAAW,CAAC,EAAC,GAAG,EAAE,KAAK,EAAE,CAAC,EAAC,CAAC,CAAA;QAE7C;YACE,EAAE,CAAC,CAAC,KAAK,CAAC,IAAI,KAAK,CAAC,CAAC,CAAC,CAAC;gBACrB,IAAI,CAAC,WAAW,CAAC,WAAW,CAAC,SAAS,CAAC,CAAA;YACzC,CAAC;YAAC,IAAI,CAAC,CAAC;gBACN,IAAI,CAAC,WAAW,CAAC,WAAW,CAAC,EAAC,GAAG,EAAE,KAAK,EAAE,GAAG,GAAG,KAAK,CAAC,IAAI,EAAC,CAAC,CAAA;YAC9D,CAAC;QACH,CAAC;IACH,CAAC,CAAA,CAAA;AACH,CAAC,CAAC,CAAA;AAEF,kBAAqB,OAAmB,EAAE,QAA4B;IACpE,OAAO,CAAC,IAAI,CAAC,QAAQ,EAAE,QAAQ,CAAC,CAAA;IAChC,MAAM,CAAC,OAAO,CAAA;AAChB,CAAC"} \ No newline at end of file diff --git a/dist/main/atom/commands/checkAllFiles.js b/dist/main/atom/commands/checkAllFiles.js new file mode 100644 index 000000000..088a34b7a --- /dev/null +++ b/dist/main/atom/commands/checkAllFiles.js @@ -0,0 +1,47 @@ +"use strict"; +Object.defineProperty(exports, "__esModule", { value: true }); +const tslib_1 = require("tslib"); +const registry_1 = require("./registry"); +const utils_1 = require("../utils"); +registry_1.commands.set("typescript:check-all-files", deps => { + return (e) => tslib_1.__awaiter(this, void 0, void 0, function* () { + if (!utils_1.commandForTypeScript(e)) { + return; + } + const { file } = utils_1.getFilePathPosition(); + const client = yield deps.getClient(file); + const projectInfo = yield client.executeProjectInfo({ + file, + needFileNameList: true + }); + const files = new Set(projectInfo.body.fileNames); + const max = files.size; + // There's no real way to know when all of the errors have been received and not every file from + // the files set is going to receive a a diagnostic event (typically some d.ts files). To counter + // that, we cancel the listener and close the progress bar after no diagnostics have been received + // for some amount of time. + let cancelTimeout; + const unregister = client.on("syntaxDiag", evt => { + clearTimeout(cancelTimeout); + cancelTimeout = setTimeout(cancel, 500); + files.delete(evt.file); + updateStatus(); + }); + deps.statusPanel.setProgress({ max, value: 0 }); + client.executeGetErrForProject({ file, delay: 0 }); + function cancel() { + files.clear(); + updateStatus(); + } + function updateStatus() { + if (files.size === 0) { + unregister(); + deps.statusPanel.setProgress(undefined); + } + else { + deps.statusPanel.setProgress({ max, value: max - files.size }); + } + } + }); +}); +//# sourceMappingURL=checkAllFiles.js.map \ No newline at end of file diff --git a/dist/main/atom/commands/checkAllFiles.js.map b/dist/main/atom/commands/checkAllFiles.js.map new file mode 100644 index 000000000..ed4f3e1a8 --- /dev/null +++ b/dist/main/atom/commands/checkAllFiles.js.map @@ -0,0 +1 @@ +{"version":3,"file":"checkAllFiles.js","sourceRoot":"","sources":["../../../../lib/main/atom/commands/checkAllFiles.ts"],"names":[],"mappings":";;;AAAA,yCAAmC;AACnC,oCAAkE;AAElE,mBAAQ,CAAC,GAAG,CAAC,4BAA4B,EAAE,IAAI;IAC7C,MAAM,CAAC,CAAM,CAAC;QACZ,EAAE,CAAC,CAAC,CAAC,4BAAoB,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC;YAC7B,MAAM,CAAA;QACR,CAAC;QAED,MAAM,EAAC,IAAI,EAAC,GAAG,2BAAmB,EAAE,CAAA;QACpC,MAAM,MAAM,GAAG,MAAM,IAAI,CAAC,SAAS,CAAC,IAAI,CAAC,CAAA;QAEzC,MAAM,WAAW,GAAG,MAAM,MAAM,CAAC,kBAAkB,CAAC;YAClD,IAAI;YACJ,gBAAgB,EAAE,IAAI;SACvB,CAAC,CAAA;QAEF,MAAM,KAAK,GAAG,IAAI,GAAG,CAAC,WAAW,CAAC,IAAK,CAAC,SAAS,CAAC,CAAA;QAClD,MAAM,GAAG,GAAG,KAAK,CAAC,IAAI,CAAA;QAEtB,gGAAgG;QAChG,iGAAiG;QACjG,kGAAkG;QAClG,2BAA2B;QAC3B,IAAI,aAAkB,CAAA;QAEtB,MAAM,UAAU,GAAG,MAAM,CAAC,EAAE,CAAC,YAAY,EAAE,GAAG;YAC5C,YAAY,CAAC,aAAa,CAAC,CAAA;YAC3B,aAAa,GAAG,UAAU,CAAC,MAAM,EAAE,GAAG,CAAC,CAAA;YAEvC,KAAK,CAAC,MAAM,CAAC,GAAG,CAAC,IAAI,CAAC,CAAA;YACtB,YAAY,EAAE,CAAA;QAChB,CAAC,CAAC,CAAA;QAEF,IAAI,CAAC,WAAW,CAAC,WAAW,CAAC,EAAC,GAAG,EAAE,KAAK,EAAE,CAAC,EAAC,CAAC,CAAA;QAC7C,MAAM,CAAC,uBAAuB,CAAC,EAAC,IAAI,EAAE,KAAK,EAAE,CAAC,EAAC,CAAC,CAAA;QAEhD;YACE,KAAK,CAAC,KAAK,EAAE,CAAA;YACb,YAAY,EAAE,CAAA;QAChB,CAAC;QAED;YACE,EAAE,CAAC,CAAC,KAAK,CAAC,IAAI,KAAK,CAAC,CAAC,CAAC,CAAC;gBACrB,UAAU,EAAE,CAAA;gBACZ,IAAI,CAAC,WAAW,CAAC,WAAW,CAAC,SAAS,CAAC,CAAA;YACzC,CAAC;YAAC,IAAI,CAAC,CAAC;gBACN,IAAI,CAAC,WAAW,CAAC,WAAW,CAAC,EAAC,GAAG,EAAE,KAAK,EAAE,GAAG,GAAG,KAAK,CAAC,IAAI,EAAC,CAAC,CAAA;YAC9D,CAAC;QACH,CAAC;IACH,CAAC,CAAA,CAAA;AACH,CAAC,CAAC,CAAA"} \ No newline at end of file diff --git a/dist/main/atom/commands/clearErrors.js b/dist/main/atom/commands/clearErrors.js new file mode 100644 index 000000000..04202926e --- /dev/null +++ b/dist/main/atom/commands/clearErrors.js @@ -0,0 +1,9 @@ +"use strict"; +Object.defineProperty(exports, "__esModule", { value: true }); +const registry_1 = require("./registry"); +registry_1.commands.set("typescript:clear-errors", deps => { + return e => { + deps.clearErrors(); + }; +}); +//# sourceMappingURL=clearErrors.js.map \ No newline at end of file diff --git a/dist/main/atom/commands/clearErrors.js.map b/dist/main/atom/commands/clearErrors.js.map new file mode 100644 index 000000000..a2e4271c0 --- /dev/null +++ b/dist/main/atom/commands/clearErrors.js.map @@ -0,0 +1 @@ +{"version":3,"file":"clearErrors.js","sourceRoot":"","sources":["../../../../lib/main/atom/commands/clearErrors.ts"],"names":[],"mappings":";;AAAA,yCAAmC;AAEnC,mBAAQ,CAAC,GAAG,CAAC,yBAAyB,EAAE,IAAI;IAC1C,MAAM,CAAC,CAAC;QACN,IAAI,CAAC,WAAW,EAAE,CAAA;IACpB,CAAC,CAAA;AACH,CAAC,CAAC,CAAA"} \ No newline at end of file diff --git a/dist/main/atom/commands/commands.js b/dist/main/atom/commands/commands.js deleted file mode 100644 index 8383a57e2..000000000 --- a/dist/main/atom/commands/commands.js +++ /dev/null @@ -1,453 +0,0 @@ -"use strict"; -function __export(m) { - for (var p in m) if (!exports.hasOwnProperty(p)) exports[p] = m[p]; -} -var parent = require("../../../worker/parent"); -var buildView = require("../buildView"); -var atomUtils = require("../atomUtils"); -var autoCompleteProvider = require("../autoCompleteProvider"); -var path = require("path"); -var renameView = require("../views/renameView"); -var contextView = require("../views/contextView"); -var fileSymbolsView = require("../views/fileSymbolsView"); -var projectSymbolsView = require("../views/projectSymbolsView"); -var typeOverlayView_1 = require("../views/typeOverlayView"); -var gotoHistory = require("../gotoHistory"); -var utils = require("../../lang/utils"); -var mainPanelView_1 = require("../views/mainPanelView"); -var astView_1 = require("../views/astView"); -var dependencyView_1 = require("../views/dependencyView"); -var simpleSelectionView_1 = require("../views/simpleSelectionView"); -var simpleOverlaySelectionView_1 = require("../views/simpleOverlaySelectionView"); -var outputFileCommands = require("./outputFileCommands"); -var moveFilesHandling_1 = require("./moveFilesHandling"); -var escapeHtml = require("escape-html"); -var rView = require("../views/rView"); -var reactCommands_1 = require("./reactCommands"); -var fileStatusCache_1 = require("../fileStatusCache"); -var json2dtsCommands_1 = require("./json2dtsCommands"); -var semanticView = require("../views/semanticView"); -__export(require("../components/componentRegistry")); -var prevCursorPositions = []; -function registerCommands() { - outputFileCommands.register(); - moveFilesHandling_1.registerRenameHandling(); - reactCommands_1.registerReactCommands(); - json2dtsCommands_1.registerJson2dtsCommands(); - function applyRefactorings(refactorings) { - var paths = atomUtils.getOpenTypeScritEditorsConsistentPaths(); - var openPathsMap = utils.createMap(paths); - var refactorPaths = Object.keys(refactorings); - var openFiles = refactorPaths.filter(function (p) { return openPathsMap[p]; }); - var closedFiles = refactorPaths.filter(function (p) { return !openPathsMap[p]; }); - atomUtils.getEditorsForAllPaths(refactorPaths) - .then(function (editorMap) { - refactorPaths.forEach(function (filePath) { - var editor = editorMap[filePath]; - editor.transact(function () { - refactorings[filePath].forEach(function (refactoring) { - var range = atomUtils.getRangeForTextSpan(editor, refactoring.span); - if (!refactoring.isNewTextSnippet) { - editor.setTextInBufferRange(range, refactoring.newText); - } - else { - var cursor = editor.getCursors()[0]; - cursor.selection.setBufferRange(range); - atomUtils.insertSnippet(refactoring.newText, editor, cursor); - } - }); - }); - }); - }); - } - atom.commands.add('atom-text-editor', 'typescript:format-code', function (e) { - if (!atomUtils.commandForTypeScript(e)) - return; - var editor = atom.workspace.getActiveTextEditor(); - var filePath = editor.getPath(); - var selection = editor.getSelectedBufferRange(); - if (selection.isEmpty()) { - parent.formatDocument({ filePath: filePath }).then(function (result) { - if (!result.edits.length) - return; - editor.transact(function () { - atomUtils.formatCode(editor, result.edits); - }); - }); - } - else { - parent.formatDocumentRange({ filePath: filePath, start: { line: selection.start.row, col: selection.start.column }, end: { line: selection.end.row, col: selection.end.column } }).then(function (result) { - if (!result.edits.length) - return; - editor.transact(function () { - atomUtils.formatCode(editor, result.edits); - }); - }); - } - }); - atom.commands.add('atom-workspace', 'typescript:build', function (e) { - if (!atomUtils.commandForTypeScript(e)) - return; - var editor = atom.workspace.getActiveTextEditor(); - var filePath = editor.getPath(); - atom.notifications.addInfo('Building'); - parent.build({ filePath: filePath }).then(function (resp) { - buildView.setBuildOutput(resp.buildOutput); - resp.tsFilesWithValidEmit.forEach(function (tsFile) { - var status = fileStatusCache_1.getFileStatus(tsFile); - status.emitDiffers = false; - }); - resp.tsFilesWithInvalidEmit.forEach(function (tsFile) { - var status = fileStatusCache_1.getFileStatus(tsFile); - status.emitDiffers = true; - }); - mainPanelView_1.panelView.updateFileStatus(filePath); - }); - }); - var handleGoToDeclaration = function (e) { - if (!atomUtils.commandForTypeScript(e)) - return; - var editor = atom.workspace.getActiveTextEditor(); - parent.getDefinitionsAtPosition(atomUtils.getFilePathPosition()).then(function (res) { - var definitions = res.definitions; - if (!definitions || !definitions.length) { - atom.notifications.addInfo('AtomTS: No definition found.'); - return; - } - if (definitions.length > 1) { - simpleSelectionView_1.simpleSelectionView({ - items: definitions, - viewForItem: function (item) { - return "\n " + item.filePath + "\n
line: " + item.position.line + "
\n "; - }, - filterKey: 'filePath', - confirmed: function (definition) { - prevCursorPositions.push({ - cursor: editor.getCursorBufferPosition(), - filePath: editor.buffer.file.path - }); - atom.workspace.open(definition.filePath, { - initialLine: definition.position.line, - initialColumn: definition.position.col - }); - } - }); - } - else { - var definition = definitions[0]; - prevCursorPositions.push({ - cursor: editor.getCursorBufferPosition(), - filePath: editor.buffer.file.path - }); - atom.workspace.open(definition.filePath, { - initialLine: definition.position.line, - initialColumn: definition.position.col - }); - } - }); - }; - var handleReturnFromDeclaration = function (e) { - var position = prevCursorPositions.pop(); - if (!position) { - atom.notifications.addInfo('AtomTS: Previous position not found.'); - return; - } - atom.workspace.open(position.filePath, { - initialLine: position.cursor.row, - initialColumn: position.cursor.column - }); - }; - atom.commands.add('atom-workspace', 'typescript:go-to-declaration', handleGoToDeclaration); - atom.commands.add('atom-text-editor', 'symbols-view:go-to-declaration', handleGoToDeclaration); - atom.commands.add('atom-workspace', 'typescript:return-from-declaration', handleReturnFromDeclaration); - atom.commands.add('atom-text-editor', 'symbols-view:return-from-declaration', handleReturnFromDeclaration); - atom.commands.add('atom-workspace', 'typescript:create-tsconfig.json-project-file', function (e) { - if (!atomUtils.commandForTypeScript(e)) - return; - var editor = atom.workspace.getActiveTextEditor(); - var filePath = editor.getPath(); - parent.createProject({ filePath: filePath }).then(function (res) { - if (res.createdFilePath) { - atom.notifications.addSuccess("tsconfig.json file created:
" + res.createdFilePath); - } - }); - }); - var theContextView; - atom.commands.add('atom-text-editor', 'typescript:context-actions', function (e) { - if (!theContextView) - theContextView = new contextView.ContextView(); - theContextView.show(); - }); - atom.commands.add('atom-text-editor', 'typescript:autocomplete', function (e) { - autoCompleteProvider.triggerAutocompletePlus(); - }); - atom.commands.add('atom-workspace', 'typescript:bas-development-testing', function (e) { - atom.commands.dispatch(atom.views.getView(atom.workspace.getActiveTextEditor()), 'typescript:dependency-view'); - }); - atom.commands.add('atom-workspace', 'typescript:toggle-semantic-view', function (e) { - if (!atomUtils.commandForTypeScript(e)) - return; - semanticView.toggle(); - }); - atom.commands.add('atom-text-editor', 'typescript:rename-refactor', function (e) { - var editor = atom.workspace.getActiveTextEditor(); - var matched = atomUtils.editorInTheseScopes([atomUtils.knownScopes.es6import, atomUtils.knownScopes.require]); - if (matched) { - var relativePath = editor.getTextInRange(editor.bufferRangeForScopeAtCursor(matched)).replace(/['"]+/g, ''); - if (!utils.pathIsRelative(relativePath)) { - atom.notifications.addInfo('AtomTS: Can only rename external modules if they are relative files!'); - return; - } - var completePath_1 = path.resolve(path.dirname(atomUtils.getCurrentPath()), relativePath) + '.ts'; - renameView.panelView.renameThis({ - autoSelect: false, - title: 'Rename File', - text: completePath_1, - openFiles: [], - closedFiles: [], - onCancel: function () { }, - onValidate: function (newText) { - if (!newText.trim()) { - return 'If you want to abort : Press esc to exit'; - } - return ''; - }, - onCommit: function (newText) { - newText = newText.trim(); - parent.getRenameFilesRefactorings({ oldPath: completePath_1, newPath: newText }) - .then(function (res) { - applyRefactorings(res.refactorings); - }); - } - }); - atom.notifications.addInfo('AtomTS: File rename comming soon!'); - } - else { - parent.getRenameInfo(atomUtils.getFilePathPosition()).then(function (res) { - if (!res.canRename) { - atom.notifications.addInfo('AtomTS: Rename not available at cursor location'); - return; - } - var paths = atomUtils.getOpenTypeScritEditorsConsistentPaths(); - var openPathsMap = utils.createMap(paths); - var refactorPaths = Object.keys(res.locations); - var openFiles = refactorPaths.filter(function (p) { return openPathsMap[p]; }); - var closedFiles = refactorPaths.filter(function (p) { return !openPathsMap[p]; }); - renameView.panelView.renameThis({ - autoSelect: true, - title: 'Rename Variable', - text: res.displayName, - openFiles: openFiles, - closedFiles: closedFiles, - onCancel: function () { }, - onValidate: function (newText) { - if (newText.replace(/\s/g, '') !== newText.trim()) { - return 'The new variable must not contain a space'; - } - if (!newText.trim()) { - return 'If you want to abort : Press esc to exit'; - } - return ''; - }, - onCommit: function (newText) { - newText = newText.trim(); - atomUtils.getEditorsForAllPaths(Object.keys(res.locations)) - .then(function (editorMap) { - Object.keys(res.locations).forEach(function (filePath) { - var editor = editorMap[filePath]; - editor.transact(function () { - res.locations[filePath].forEach(function (textSpan) { - var range = atomUtils.getRangeForTextSpan(editor, textSpan); - editor.setTextInBufferRange(range, newText); - }); - }); - }); - }); - } - }); - }); - } - }); - atom.commands.add('atom-workspace', 'typescript:show-type', function (e) { - var editor = atom.workspace.getActiveTextEditor(); - var editorView = atom.views.getView(editor); - var cursor = editor.getLastCursor(); - var position = atomUtils.getEditorPositionForBufferPosition(editor, cursor.getBufferPosition()); - var filePath = editor.getPath(); - parent.quickInfo({ filePath: filePath, position: position }).then(function (resp) { - if (resp.valid) { - var decoration = editor.decorateMarker(cursor.getMarker(), { - type: 'overlay', - item: typeOverlayView_1.create(resp.name, resp.comment) - }); - var onKeydown = function (e) { - if (e.keyCode == 27) { - destroyTypeOverlay(); - } - }; - var destroyTypeOverlay = function () { - decoration.destroy(); - cursorListener.dispose(); - editorView.removeEventListener('blur', destroyTypeOverlay); - editorView.removeEventListener('keydown', onKeydown); - }; - var cursorListener = editor.onDidChangeCursorPosition(destroyTypeOverlay); - editorView.addEventListener('blur', destroyTypeOverlay); - editorView.addEventListener('keydown', onKeydown); - } - }); - }); - atom.commands.add('atom-workspace', 'typescript:go-to-next', function (e) { - gotoHistory.gotoNext(); - }); - atom.commands.add('atom-workspace', 'typescript:go-to-previous', function (e) { - gotoHistory.gotoPrevious(); - }); - atom.commands.add('atom-workspace', 'typescript:find-references', function (e) { - if (!atomUtils.commandForTypeScript(e)) - return; - parent.getReferences(atomUtils.getFilePathPosition()).then(function (res) { - mainPanelView_1.panelView.setReferences(res.references); - simpleSelectionView_1.simpleSelectionView({ - items: res.references, - viewForItem: function (item) { - return "
\n " + atom.project.relativize(item.filePath) + "\n
line: " + (item.position.line + 1) + "
\n " + escapeHtml(item.preview) + "\n
"; - }, - filterKey: utils.getName(function () { return res.references[0].filePath; }), - confirmed: function (definition) { - atom.workspace.open(definition.filePath, { - initialLine: definition.position.line, - initialColumn: definition.position.col - }); - } - }); - }); - }); - var theFileSymbolsView; - var showFileSymbols = utils.debounce(function (filePath) { - if (!theFileSymbolsView) - theFileSymbolsView = new fileSymbolsView.FileSymbolsView(); - parent.getNavigationBarItems({ filePath: filePath }).then(function (res) { - theFileSymbolsView.setNavBarItems(res.items, filePath); - theFileSymbolsView.show(); - }); - }, 400); - atom.commands.add('.platform-linux atom-text-editor, .platform-darwin atom-text-editor,.platform-win32 atom-text-editor', 'symbols-view:toggle-file-symbols', function (e) { - var editor = atom.workspace.getActiveTextEditor(); - if (!editor) - return false; - if (path.extname(editor.getPath()) !== '.ts' && path.extname(editor.getPath()) !== '.tsx') - return false; - e.abortKeyBinding(); - var filePath = editor.getPath(); - showFileSymbols(filePath); - }); - var theProjectSymbolsView; - var showProjectSymbols = utils.debounce(function (filePath) { - if (!theProjectSymbolsView) - theProjectSymbolsView = new projectSymbolsView.ProjectSymbolsView(); - parent.getNavigateToItems({ filePath: filePath }).then(function (res) { - theProjectSymbolsView.setNavBarItems(res.items); - theProjectSymbolsView.show(); - }); - }, 400); - atom.commands.add('.platform-linux atom-text-editor, .platform-darwin atom-text-editor,.platform-win32 atom-text-editor', 'symbols-view:toggle-project-symbols', function (e) { - var editor = atom.workspace.getActiveTextEditor(); - if (!editor) - return false; - if (path.extname(editor.getPath()) !== '.ts') - return false; - e.abortKeyBinding(); - var filePath = editor.getPath(); - showProjectSymbols(filePath); - }); - atomUtils.registerOpener({ - commandSelector: 'atom-text-editor', - commandName: 'typescript:ast', - uriProtocol: astView_1.astURI, - getData: function () { - return { - text: atom.workspace.getActiveTextEditor().getText(), - filePath: atomUtils.getCurrentPath() - }; - }, - onOpen: function (data) { - return new astView_1.AstView(data.filePath, data.text, false); - } - }); - atomUtils.registerOpener({ - commandSelector: 'atom-text-editor', - commandName: 'typescript:ast-full', - uriProtocol: astView_1.astURIFull, - getData: function () { - return { - text: atom.workspace.getActiveTextEditor().getText(), - filePath: atomUtils.getCurrentPath() - }; - }, - onOpen: function (data) { - return new astView_1.AstView(data.filePath, data.text, true); - } - }); - atomUtils.registerOpener({ - commandSelector: 'atom-workspace', - commandName: 'typescript:dependency-view', - uriProtocol: dependencyView_1.dependencyURI, - getData: function () { - return { - filePath: atomUtils.getCurrentPath() - }; - }, - onOpen: function (data) { - return new dependencyView_1.DependencyView(data.filePath); - } - }); - atom.commands.add('atom-text-editor', 'typescript:quick-fix', function (e) { - if (!atomUtils.commandForTypeScript(e)) - return; - var editor = atomUtils.getActiveEditor(); - var query = atomUtils.getFilePathPosition(); - parent.getQuickFixes(query).then(function (result) { - if (!result.fixes.length) { - atom.notifications.addInfo('AtomTS: No QuickFixes for current cursor position'); - return; - } - simpleOverlaySelectionView_1.default({ - items: result.fixes, - viewForItem: function (item) { - return "
\n " + (item.isNewTextSnippet ? '' : '') + "\n " + escapeHtml(item.display) + "\n
"; - }, - filterKey: 'display', - confirmed: function (item) { - parent.applyQuickFix({ key: item.key, filePath: query.filePath, position: query.position }).then(function (res) { - applyRefactorings(res.refactorings); - }); - } - }, editor); - }); - }); - atomUtils.registerOpener({ - commandSelector: 'atom-workspace', - commandName: 'typescript:testing-r-view', - uriProtocol: rView.RView.protocol, - getData: function () { return atomUtils.getFilePath(); }, - onOpen: function (data) { return new rView.RView({ - icon: 'repo-forked', - title: 'React View', - filePath: data.filePath, - }); }, - }); - atom.commands.add('atom-workspace', 'typescript:sync', function (e) { - if (!atomUtils.commandForTypeScript(e)) - return; - mainPanelView_1.panelView.softReset(); - }); - atom.commands.add('atom-text-editor', 'typescript:toggle-breakpoint', function (e) { - if (!atomUtils.commandForTypeScript(e)) - return; - parent.toggleBreakpoint(atomUtils.getFilePathPosition()).then(function (res) { - applyRefactorings(res.refactorings); - }); - }); -} -exports.registerCommands = registerCommands; diff --git a/dist/main/atom/commands/findReferences.js b/dist/main/atom/commands/findReferences.js new file mode 100644 index 000000000..aa36756c1 --- /dev/null +++ b/dist/main/atom/commands/findReferences.js @@ -0,0 +1,36 @@ +"use strict"; +Object.defineProperty(exports, "__esModule", { value: true }); +const tslib_1 = require("tslib"); +const registry_1 = require("./registry"); +const utils_1 = require("../utils"); +const simpleSelectionView_1 = require("../views/simpleSelectionView"); +const escapeHtml = require("escape-html"); +registry_1.commands.set("typescript:find-references", deps => { + return (e) => tslib_1.__awaiter(this, void 0, void 0, function* () { + if (!utils_1.commandForTypeScript(e)) { + return; + } + const location = utils_1.getFilePathPosition(); + const client = yield deps.getClient(location.file); + const result = yield client.executeReferences(location); + simpleSelectionView_1.simpleSelectionView({ + items: result.body.refs, + viewForItem: item => { + return `
+ ${atom.project.relativize(item.file)} +
line: ${item.start.line}
+ ${escapeHtml(item.lineText.trim())} +
`; + }, + filterKey: 'filePath', + confirmed: item => open(item) + }); + function open(item) { + atom.workspace.open(item.file, { + initialLine: item.start.line - 1, + initialColumn: item.start.offset - 1 + }); + } + }); +}); +//# sourceMappingURL=findReferences.js.map \ No newline at end of file diff --git a/dist/main/atom/commands/findReferences.js.map b/dist/main/atom/commands/findReferences.js.map new file mode 100644 index 000000000..0e7d90e0a --- /dev/null +++ b/dist/main/atom/commands/findReferences.js.map @@ -0,0 +1 @@ +{"version":3,"file":"findReferences.js","sourceRoot":"","sources":["../../../../lib/main/atom/commands/findReferences.ts"],"names":[],"mappings":";;;AAAA,yCAAmC;AACnC,oCAAkE;AAClE,sEAAgE;AAChE,0CAA0C;AAE1C,mBAAQ,CAAC,GAAG,CAAC,4BAA4B,EAAE,IAAI;IAC7C,MAAM,CAAC,CAAM,CAAC;QACZ,EAAE,CAAC,CAAC,CAAC,4BAAoB,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC;YAC7B,MAAM,CAAA;QACR,CAAC;QAED,MAAM,QAAQ,GAAG,2BAAmB,EAAE,CAAA;QACtC,MAAM,MAAM,GAAG,MAAM,IAAI,CAAC,SAAS,CAAC,QAAQ,CAAC,IAAI,CAAC,CAAA;QAClD,MAAM,MAAM,GAAG,MAAM,MAAM,CAAC,iBAAiB,CAAC,QAAQ,CAAC,CAAA;QAEvD,yCAAmB,CAAC;YAClB,KAAK,EAAE,MAAM,CAAC,IAAK,CAAC,IAAI;YACxB,WAAW,EAAE,IAAI;gBACf,MAAM,CAAC;kBACG,IAAI,CAAC,OAAO,CAAC,UAAU,CAAC,IAAI,CAAC,IAAI,CAAC;0CACV,IAAI,CAAC,KAAK,CAAC,IAAI;qBACpC,UAAU,CAAC,IAAI,CAAC,QAAQ,CAAC,IAAI,EAAE,CAAC;eACtC,CAAA;YACT,CAAC;YACD,SAAS,EAAE,UAAU;YACrB,SAAS,EAAE,IAAI,IAAI,IAAI,CAAC,IAAI,CAAC;SAC9B,CAAC,CAAA;QAEF,cAAc,IAA2D;YACvE,IAAI,CAAC,SAAS,CAAC,IAAI,CAAC,IAAI,CAAC,IAAI,EAAE;gBAC7B,WAAW,EAAE,IAAI,CAAC,KAAK,CAAC,IAAI,GAAG,CAAC;gBAChC,aAAa,EAAE,IAAI,CAAC,KAAK,CAAC,MAAM,GAAG,CAAC;aACrC,CAAC,CAAA;QACJ,CAAC;IACH,CAAC,CAAA,CAAA;AACH,CAAC,CAAC,CAAA"} \ No newline at end of file diff --git a/dist/main/atom/commands/formatCode.js b/dist/main/atom/commands/formatCode.js new file mode 100644 index 000000000..22d6599e9 --- /dev/null +++ b/dist/main/atom/commands/formatCode.js @@ -0,0 +1,59 @@ +"use strict"; +Object.defineProperty(exports, "__esModule", { value: true }); +const tslib_1 = require("tslib"); +const registry_1 = require("./registry"); +const utils_1 = require("../utils"); +const atomts_1 = require("../../atomts"); +registry_1.commands.set("typescript:format-code", deps => { + return (e) => tslib_1.__awaiter(this, void 0, void 0, function* () { + if (!utils_1.commandForTypeScript(e)) { + return; + } + const editor = atom.workspace.getActiveTextEditor(); + const filePath = editor.getPath(); + const ranges = []; + for (const selection of editor.getSelectedBufferRanges()) { + if (!selection.isEmpty()) { + ranges.push(utils_1.rangeToLocationRange(selection)); + } + } + // Format the whole document if there are no ranges added + if (ranges.length === 0) { + const end = editor.buffer.getEndPosition(); + ranges.push({ + line: 1, + offset: 1, + endLine: end.row + 1, + endOffset: end.column + 1 + }); + } + const client = yield deps.getClient(filePath); + const options = yield getProjectCodeSettings(filePath); + // Newer versions of tsserver ignore the options argument so we need to call + // configure with the format code options to make the format command do anything. + client.executeConfigure({ + formatOptions: options + }); + const edits = []; + // Collect all edits together so we can update everything in a single transaction + for (const range of ranges) { + const result = yield client.executeFormat(Object.assign({}, range, { options, file: filePath })); + if (result.body) { + edits.push(...result.body); + } + } + if (edits.length > 0) { + editor.transact(() => { + utils_1.formatCode(editor, edits); + }); + } + }); +}); +function getProjectCodeSettings(filePath) { + return tslib_1.__awaiter(this, void 0, void 0, function* () { + const config = yield atomts_1.loadProjectConfig(filePath); + const options = config.formatCodeOptions; + return Object.assign({ indentSize: atom.config.get("editor.tabLength"), tabSize: atom.config.get("editor.tabLength") }, options); + }); +} +//# sourceMappingURL=formatCode.js.map \ No newline at end of file diff --git a/dist/main/atom/commands/formatCode.js.map b/dist/main/atom/commands/formatCode.js.map new file mode 100644 index 000000000..f50588b13 --- /dev/null +++ b/dist/main/atom/commands/formatCode.js.map @@ -0,0 +1 @@ +{"version":3,"file":"formatCode.js","sourceRoot":"","sources":["../../../../lib/main/atom/commands/formatCode.ts"],"names":[],"mappings":";;;AAAA,yCAAmC;AACnC,oCAOiB;AACjB,yCAA8C;AAE9C,mBAAQ,CAAC,GAAG,CAAC,wBAAwB,EAAE,IAAI;IACzC,MAAM,CAAC,CAAM,CAAC;QACZ,EAAE,CAAC,CAAC,CAAC,4BAAoB,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC;YAC7B,MAAM,CAAA;QACR,CAAC;QAED,MAAM,MAAM,GAAG,IAAI,CAAC,SAAS,CAAC,mBAAmB,EAAE,CAAA;QACnD,MAAM,QAAQ,GAAG,MAAM,CAAC,OAAO,EAAE,CAAA;QACjC,MAAM,MAAM,GAAyB,EAAE,CAAA;QAEvC,GAAG,CAAC,CAAC,MAAM,SAAS,IAAI,MAAM,CAAC,uBAAuB,EAAE,CAAC,CAAC,CAAC;YACzD,EAAE,CAAC,CAAC,CAAC,SAAS,CAAC,OAAO,EAAE,CAAC,CAAC,CAAC;gBACzB,MAAM,CAAC,IAAI,CAAC,4BAAoB,CAAC,SAAS,CAAC,CAAC,CAAA;YAC9C,CAAC;QACH,CAAC;QAED,yDAAyD;QACzD,EAAE,CAAC,CAAC,MAAM,CAAC,MAAM,KAAK,CAAC,CAAC,CAAC,CAAC;YACxB,MAAM,GAAG,GAAG,MAAM,CAAC,MAAM,CAAC,cAAc,EAAE,CAAA;YAC1C,MAAM,CAAC,IAAI,CAAC;gBACV,IAAI,EAAE,CAAC;gBACP,MAAM,EAAE,CAAC;gBACT,OAAO,EAAE,GAAG,CAAC,GAAG,GAAG,CAAC;gBACpB,SAAS,EAAE,GAAG,CAAC,MAAM,GAAG,CAAC;aAC1B,CAAC,CAAA;QACJ,CAAC;QAED,MAAM,MAAM,GAAG,MAAM,IAAI,CAAC,SAAS,CAAC,QAAQ,CAAC,CAAA;QAC7C,MAAM,OAAO,GAAG,MAAM,sBAAsB,CAAC,QAAQ,CAAC,CAAA;QAEtD,4EAA4E;QAC5E,iFAAiF;QACjF,MAAM,CAAC,gBAAgB,CAAC;YACtB,aAAa,EAAE,OAAO;SACvB,CAAC,CAAA;QAEF,MAAM,KAAK,GAAe,EAAE,CAAA;QAE5B,iFAAiF;QACjF,GAAG,CAAC,CAAC,MAAM,KAAK,IAAI,MAAM,CAAC,CAAC,CAAC;YAC3B,MAAM,MAAM,GAAG,MAAM,MAAM,CAAC,aAAa,mBAAK,KAAK,IAAE,OAAO,EAAE,IAAI,EAAE,QAAQ,IAAE,CAAA;YAC9E,EAAE,CAAC,CAAC,MAAM,CAAC,IAAI,CAAC,CAAC,CAAC;gBAChB,KAAK,CAAC,IAAI,CAAC,GAAG,MAAM,CAAC,IAAI,CAAC,CAAA;YAC5B,CAAC;QACH,CAAC;QAED,EAAE,CAAC,CAAC,KAAK,CAAC,MAAM,GAAG,CAAC,CAAC,CAAC,CAAC;YACrB,MAAM,CAAC,QAAQ,CAAC;gBACd,kBAAU,CAAC,MAAM,EAAE,KAAK,CAAC,CAAA;YAC3B,CAAC,CAAC,CAAA;QACJ,CAAC;IACH,CAAC,CAAA,CAAA;AACH,CAAC,CAAC,CAAA;AAEF,gCAAsC,QAAgB;;QACpD,MAAM,MAAM,GAAG,MAAM,0BAAiB,CAAC,QAAQ,CAAC,CAAA;QAChD,MAAM,OAAO,GAAG,MAAM,CAAC,iBAAiB,CAAA;QAExC,MAAM,iBACJ,UAAU,EAAE,IAAI,CAAC,MAAM,CAAC,GAAG,CAAC,kBAAkB,CAAC,EAC/C,OAAO,EAAE,IAAI,CAAC,MAAM,CAAC,GAAG,CAAC,kBAAkB,CAAC,IACzC,OAAO,EACX;IACH,CAAC;CAAA"} \ No newline at end of file diff --git a/dist/main/atom/commands/goToDeclaration.js b/dist/main/atom/commands/goToDeclaration.js new file mode 100644 index 000000000..2fecf9ecc --- /dev/null +++ b/dist/main/atom/commands/goToDeclaration.js @@ -0,0 +1,57 @@ +"use strict"; +Object.defineProperty(exports, "__esModule", { value: true }); +const tslib_1 = require("tslib"); +const registry_1 = require("./registry"); +const utils_1 = require("../utils"); +const simpleSelectionView_1 = require("../views/simpleSelectionView"); +const prevCursorPositions = []; +function open(item) { + atom.workspace.open(item.file, { + initialLine: item.start.line - 1, + initialColumn: item.start.offset - 1 + }); +} +registry_1.commands.set("typescript:go-to-declaration", deps => { + return (e) => tslib_1.__awaiter(this, void 0, void 0, function* () { + if (!utils_1.commandForTypeScript(e)) { + return; + } + const location = utils_1.getFilePathPosition(); + const client = yield deps.getClient(location.file); + const result = yield client.executeDefinition(location); + if (result.body.length > 1) { + simpleSelectionView_1.simpleSelectionView({ + items: result.body, + viewForItem: item => { + return ` + ${item.file} +
line: ${item.start.line}
+ `; + }, + filterKey: 'filePath', + confirmed: item => { + prevCursorPositions.push(location); + open(item); + } + }); + } + else { + prevCursorPositions.push(location); + open(result.body[0]); + } + }); +}); +registry_1.commands.set("typescript:return-from-declaration", deps => { + return (e) => tslib_1.__awaiter(this, void 0, void 0, function* () { + const position = prevCursorPositions.pop(); + if (!position) { + atom.notifications.addInfo('AtomTS: Previous position not found.'); + return; + } + open({ + file: position.file, + start: { line: position.line, offset: position.offset } + }); + }); +}); +//# sourceMappingURL=goToDeclaration.js.map \ No newline at end of file diff --git a/dist/main/atom/commands/goToDeclaration.js.map b/dist/main/atom/commands/goToDeclaration.js.map new file mode 100644 index 000000000..a6c388910 --- /dev/null +++ b/dist/main/atom/commands/goToDeclaration.js.map @@ -0,0 +1 @@ +{"version":3,"file":"goToDeclaration.js","sourceRoot":"","sources":["../../../../lib/main/atom/commands/goToDeclaration.ts"],"names":[],"mappings":";;;AAAA,yCAAmC;AACnC,oCAAqF;AACrF,sEAAgE;AAEhE,MAAM,mBAAmB,GAAuB,EAAE,CAAC;AAEnD,cAAc,IAA2D;IACtE,IAAI,CAAC,SAAS,CAAC,IAAI,CAAC,IAAI,CAAC,IAAI,EAAE;QAC7B,WAAW,EAAE,IAAI,CAAC,KAAK,CAAC,IAAI,GAAG,CAAC;QAChC,aAAa,EAAE,IAAI,CAAC,KAAK,CAAC,MAAM,GAAG,CAAC;KACrC,CAAC,CAAA;AACL,CAAC;AAED,mBAAQ,CAAC,GAAG,CAAC,8BAA8B,EAAE,IAAI;IAC/C,MAAM,CAAC,CAAM,CAAC;QACZ,EAAE,CAAC,CAAC,CAAC,4BAAoB,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC;YAC7B,MAAM,CAAA;QACR,CAAC;QAED,MAAM,QAAQ,GAAG,2BAAmB,EAAE,CAAA;QACtC,MAAM,MAAM,GAAG,MAAM,IAAI,CAAC,SAAS,CAAC,QAAQ,CAAC,IAAI,CAAC,CAAA;QAClD,MAAM,MAAM,GAAG,MAAM,MAAM,CAAC,iBAAiB,CAAC,QAAQ,CAAC,CAAA;QAEvD,EAAE,CAAC,CAAC,MAAM,CAAC,IAAK,CAAC,MAAM,GAAG,CAAC,CAAC,CAAC,CAAC;YAC5B,yCAAmB,CAAC;gBAClB,KAAK,EAAE,MAAM,CAAC,IAAK;gBACnB,WAAW,EAAE,IAAI;oBACb,MAAM,CAAC;wBACK,IAAI,CAAC,IAAI;gDACe,IAAI,CAAC,KAAK,CAAC,IAAI;aAClD,CAAA;gBACL,CAAC;gBACD,SAAS,EAAE,UAAU;gBACrB,SAAS,EAAE,IAAI;oBACZ,mBAAmB,CAAC,IAAI,CAAC,QAAQ,CAAC,CAAC;oBACnC,IAAI,CAAC,IAAI,CAAC,CAAA;gBACb,CAAC;aACF,CAAC,CAAA;QACJ,CAAC;QAAC,IAAI,CAAC,CAAC;YACN,mBAAmB,CAAC,IAAI,CAAC,QAAQ,CAAC,CAAC;YACnC,IAAI,CAAC,MAAM,CAAC,IAAK,CAAC,CAAC,CAAC,CAAC,CAAA;QACvB,CAAC;IACH,CAAC,CAAA,CAAA;AACH,CAAC,CAAC,CAAC;AAEH,mBAAQ,CAAC,GAAG,CAAC,oCAAoC,EAAE,IAAI;IACpD,MAAM,CAAC,CAAM,CAAC;QACX,MAAM,QAAQ,GAAG,mBAAmB,CAAC,GAAG,EAAE,CAAC;QAC3C,EAAE,CAAC,CAAC,CAAC,QAAQ,CAAC,CAAC,CAAC;YACb,IAAI,CAAC,aAAa,CAAC,OAAO,CAAC,sCAAsC,CAAC,CAAC;YACnE,MAAM,CAAC;QACV,CAAC;QACD,IAAI,CAAC;YACF,IAAI,EAAE,QAAQ,CAAC,IAAI;YACnB,KAAK,EAAE,EAAE,IAAI,EAAE,QAAQ,CAAC,IAAI,EAAE,MAAM,EAAE,QAAQ,CAAC,MAAM,EAAE;SACzD,CAAC,CAAC;IACN,CAAC,CAAA,CAAA;AACJ,CAAC,CAAC,CAAC"} \ No newline at end of file diff --git a/dist/main/atom/commands/index.js b/dist/main/atom/commands/index.js new file mode 100644 index 000000000..c23577088 --- /dev/null +++ b/dist/main/atom/commands/index.js @@ -0,0 +1,18 @@ +"use strict"; +Object.defineProperty(exports, "__esModule", { value: true }); +const registry_1 = require("./registry"); +// Import all of the command files for their side effects +require("./build"); +require("./checkAllFiles"); +require("./clearErrors"); +require("./formatCode"); +require("./findReferences"); +require("./goToDeclaration"); +require("./renameRefactor"); +function registerCommands(deps) { + for (const [name, command] of registry_1.commands) { + atom.commands.add("atom-workspace", name, command(deps)); + } +} +exports.registerCommands = registerCommands; +//# sourceMappingURL=index.js.map \ No newline at end of file diff --git a/dist/main/atom/commands/index.js.map b/dist/main/atom/commands/index.js.map new file mode 100644 index 000000000..8b0e6fe63 --- /dev/null +++ b/dist/main/atom/commands/index.js.map @@ -0,0 +1 @@ +{"version":3,"file":"index.js","sourceRoot":"","sources":["../../../../lib/main/atom/commands/index.ts"],"names":[],"mappings":";;AAAA,yCAAiD;AAEjD,yDAAyD;AACzD,mBAAgB;AAChB,2BAAwB;AACxB,yBAAsB;AACtB,wBAAqB;AACrB,4BAAyB;AACzB,6BAA0B;AAC1B,4BAAyB;AAEzB,0BAAiC,IAAkB;IAEjD,GAAG,CAAC,CAAC,MAAM,CAAC,IAAI,EAAE,OAAO,CAAC,IAAI,mBAAQ,CAAC,CAAC,CAAC;QACvC,IAAI,CAAC,QAAQ,CAAC,GAAG,CAAC,gBAAgB,EAAE,IAAI,EAAE,OAAO,CAAC,IAAI,CAAC,CAAC,CAAA;IAC1D,CAAC;AACH,CAAC;AALD,4CAKC"} \ No newline at end of file diff --git a/dist/main/atom/commands/json2dtsCommands.js b/dist/main/atom/commands/json2dtsCommands.js deleted file mode 100644 index 4fd16c14a..000000000 --- a/dist/main/atom/commands/json2dtsCommands.js +++ /dev/null @@ -1,16 +0,0 @@ -"use strict"; -var atomUtils = require("../atomUtils"); -var json2dts_1 = require("../../json2dts/json2dts"); -function registerJson2dtsCommands() { - atom.commands.add('atom-workspace', 'typescript:JSON-to-Definition', function (e) { - if (!atomUtils.commandForTypeScript(e)) - return; - var editor = atom.workspace.getActiveTextEditor(); - var filePath = editor.getPath(); - var selection = editor.getSelectedBufferRange(); - var text = editor.getSelectedText(); - var range = editor.getSelectedBufferRange(); - editor.setTextInBufferRange(range, json2dts_1.convert(text)); - }); -} -exports.registerJson2dtsCommands = registerJson2dtsCommands; diff --git a/dist/main/atom/commands/moveFilesHandling.js b/dist/main/atom/commands/moveFilesHandling.js deleted file mode 100644 index a085ae1cc..000000000 --- a/dist/main/atom/commands/moveFilesHandling.js +++ /dev/null @@ -1,4 +0,0 @@ -"use strict"; -function registerRenameHandling() { -} -exports.registerRenameHandling = registerRenameHandling; diff --git a/dist/main/atom/commands/outputFileCommands.js b/dist/main/atom/commands/outputFileCommands.js deleted file mode 100644 index 7ad193d1c..000000000 --- a/dist/main/atom/commands/outputFileCommands.js +++ /dev/null @@ -1,58 +0,0 @@ -"use strict"; -var atomUtils = require("../atomUtils"); -var parent = require("../../../worker/parent"); -var child_process_1 = require("child_process"); -var path = require("path"); -function register() { - atom.commands.add('atom-workspace', 'typescript:output-toggle', function (e) { - if (!atomUtils.commandForTypeScript(e)) - return; - var query = atomUtils.getFilePath(); - var previousActivePane = atom.workspace.getActivePane(); - parent.getOutputJs(query).then(function (res) { - if (!res.jsFilePath) { - atom.notifications.addInfo('AtomTS: No emit for this file'); - return; - } - else { - var uri = res.jsFilePath.split("/").join(path.sep); - var previewPane = atom.workspace.paneForURI(uri); - if (previewPane) { - previewPane.destroyItem(previewPane.itemForURI(uri)); - } - else { - atom.workspace.open(res.jsFilePath, { split: "right" }).then(function () { - previousActivePane.activate(); - }); - } - } - }); - }); - atom.commands.add('atom-workspace', 'typescript:output-file-execute-in-node', function (e) { - if (!atomUtils.commandForTypeScript(e)) - return; - var query = atomUtils.getFilePath(); - parent.getOutputJs(query).then(function (res) { - if (!res.jsFilePath) { - atom.notifications.addInfo('AtomTS: No emit for this file'); - return; - } - else { - var command = "node " + path.basename(res.jsFilePath); - console.log(command); - child_process_1.exec(command, { - cwd: path.dirname(res.jsFilePath), - env: { - ELECTRON_RUN_AS_NODE: 1, - }, - }, function (err, stdout, stderr) { - console.log(stdout); - if (stderr.toString().trim().length) { - console.error(stderr); - } - }); - } - }); - }); -} -exports.register = register; diff --git a/dist/main/atom/commands/reactCommand.js b/dist/main/atom/commands/reactCommand.js deleted file mode 100644 index 22ecfd5d6..000000000 --- a/dist/main/atom/commands/reactCommand.js +++ /dev/null @@ -1,14 +0,0 @@ -var atomUtils = require("../atomUtils"); -function register() { - atom.commands.add('atom-workspace', 'typescript:HTML-to-TSX', function (e) { - if (!atomUtils.commandForTypeScript(e)) - return; - var editor = atom.workspace.getActiveTextEditor(); - var filePath = editor.getPath(); - var selection = editor.getSelectedBufferRange(); - var text = editor.getSelectedText(); - var range = editor.getSelectedBufferRange(); - editor.setTextInBufferRange(range, "foo"); - }); -} -exports.register = register; diff --git a/dist/main/atom/commands/reactCommands.js b/dist/main/atom/commands/reactCommands.js deleted file mode 100644 index 2adb4c4dc..000000000 --- a/dist/main/atom/commands/reactCommands.js +++ /dev/null @@ -1,16 +0,0 @@ -"use strict"; -var atomUtils = require("../atomUtils"); -var htmltotsx_1 = require("../../react/htmltotsx"); -function registerReactCommands() { - atom.commands.add('atom-workspace', 'typescript:HTML-to-TSX', function (e) { - if (!atomUtils.commandForTypeScript(e)) - return; - var editor = atom.workspace.getActiveTextEditor(); - var filePath = editor.getPath(); - var selection = editor.getSelectedBufferRange(); - var text = editor.getSelectedText(); - var range = editor.getSelectedBufferRange(); - editor.setTextInBufferRange(range, htmltotsx_1.convert(text, 4)); - }); -} -exports.registerReactCommands = registerReactCommands; diff --git a/dist/main/atom/commands/registry.js b/dist/main/atom/commands/registry.js new file mode 100644 index 000000000..0d73c9dad --- /dev/null +++ b/dist/main/atom/commands/registry.js @@ -0,0 +1,7 @@ +"use strict"; +Object.defineProperty(exports, "__esModule", { value: true }); +// To allow using dependency injection, but avoid having to type a lot of boilerplate, we have the +// individual command files register themselves in the below map. When the package is initializing, +// the constructors are passed the deps and return the actual commands handlers. +exports.commands = new Map(); +//# sourceMappingURL=registry.js.map \ No newline at end of file diff --git a/dist/main/atom/commands/registry.js.map b/dist/main/atom/commands/registry.js.map new file mode 100644 index 000000000..7f1f02f14 --- /dev/null +++ b/dist/main/atom/commands/registry.js.map @@ -0,0 +1 @@ +{"version":3,"file":"registry.js","sourceRoot":"","sources":["../../../../lib/main/atom/commands/registry.ts"],"names":[],"mappings":";;AAiBA,kGAAkG;AAClG,mGAAmG;AACnG,gFAAgF;AACnE,QAAA,QAAQ,GAAoC,IAAI,GAAG,EAAE,CAAA"} \ No newline at end of file diff --git a/dist/main/atom/commands/renameRefactor.js b/dist/main/atom/commands/renameRefactor.js new file mode 100644 index 000000000..864173d90 --- /dev/null +++ b/dist/main/atom/commands/renameRefactor.js @@ -0,0 +1,49 @@ +"use strict"; +Object.defineProperty(exports, "__esModule", { value: true }); +const tslib_1 = require("tslib"); +const registry_1 = require("./registry"); +const utils_1 = require("../utils"); +const utils_2 = require("../utils"); +registry_1.commands.set("typescript:rename-refactor", deps => { + return (e) => tslib_1.__awaiter(this, void 0, void 0, function* () { + if (!utils_1.commandForTypeScript(e)) { + return; + } + const location = utils_1.getFilePathPosition(); + const client = yield deps.getClient(location.file); + const response = yield client.executeRename(location); + const { info, locs } = response.body; + if (!info.canRename) { + return atom.notifications.addInfo("AtomTS: Rename not available at cursor location"); + } + const newName = yield deps.renameView.showRenameDialog({ + autoSelect: true, + title: "Rename Variable", + text: info.displayName, + onValidate: (newText) => { + if (newText.replace(/\s/g, "") !== newText.trim()) { + return "The new variable must not contain a space"; + } + if (!newText.trim()) { + return "If you want to abort : Press esc to exit"; + } + return ""; + } + }); + locs.map((loc) => tslib_1.__awaiter(this, void 0, void 0, function* () { + const { buffer, isOpen } = yield deps.getTypescriptBuffer(loc.file); + buffer.buffer.transact(() => { + for (const span of loc.locs) { + buffer.buffer.setTextInRange(utils_2.spanToRange(span), newName); + } + }); + if (!isOpen) { + buffer.buffer.save(); + buffer.on("saved", () => { + buffer.buffer.destroy(); + }); + } + })); + }); +}); +//# sourceMappingURL=renameRefactor.js.map \ No newline at end of file diff --git a/dist/main/atom/commands/renameRefactor.js.map b/dist/main/atom/commands/renameRefactor.js.map new file mode 100644 index 000000000..6a2a06684 --- /dev/null +++ b/dist/main/atom/commands/renameRefactor.js.map @@ -0,0 +1 @@ +{"version":3,"file":"renameRefactor.js","sourceRoot":"","sources":["../../../../lib/main/atom/commands/renameRefactor.ts"],"names":[],"mappings":";;;AAAA,yCAAmC;AACnC,oCAAkE;AAClE,oCAAoC;AAEpC,mBAAQ,CAAC,GAAG,CAAC,4BAA4B,EAAE,IAAI;IAC7C,MAAM,CAAC,CAAM,CAAC;QACZ,EAAE,CAAC,CAAC,CAAC,4BAAoB,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC;YAC7B,MAAM,CAAA;QACR,CAAC;QAED,MAAM,QAAQ,GAAG,2BAAmB,EAAE,CAAA;QACtC,MAAM,MAAM,GAAG,MAAM,IAAI,CAAC,SAAS,CAAC,QAAQ,CAAC,IAAI,CAAC,CAAA;QAClD,MAAM,QAAQ,GAAG,MAAM,MAAM,CAAC,aAAa,CAAC,QAAQ,CAAC,CAAA;QACrD,MAAM,EAAC,IAAI,EAAE,IAAI,EAAC,GAAG,QAAQ,CAAC,IAAK,CAAA;QAEnC,EAAE,CAAC,CAAC,CAAC,IAAI,CAAC,SAAS,CAAC,CAAC,CAAC;YACpB,MAAM,CAAC,IAAI,CAAC,aAAa,CAAC,OAAO,CAAC,iDAAiD,CAAC,CAAA;QACtF,CAAC;QAED,MAAM,OAAO,GAAG,MAAM,IAAI,CAAC,UAAU,CAAC,gBAAgB,CAAC;YACrD,UAAU,EAAE,IAAI;YAChB,KAAK,EAAE,iBAAiB;YACxB,IAAI,EAAE,IAAI,CAAC,WAAW;YACtB,UAAU,EAAE,CAAC,OAAO;gBAClB,EAAE,CAAC,CAAC,OAAO,CAAC,OAAO,CAAC,KAAK,EAAE,EAAE,CAAC,KAAK,OAAO,CAAC,IAAI,EAAE,CAAC,CAAC,CAAC;oBAChD,MAAM,CAAC,2CAA2C,CAAA;gBACtD,CAAC;gBACD,EAAE,CAAC,CAAC,CAAC,OAAO,CAAC,IAAI,EAAE,CAAC,CAAC,CAAC;oBAClB,MAAM,CAAC,0CAA0C,CAAA;gBACrD,CAAC;gBACD,MAAM,CAAC,EAAE,CAAA;YACX,CAAC;SACF,CAAC,CAAA;QAEF,IAAI,CAAC,GAAG,CAAC,CAAM,GAAG;YAChB,MAAM,EAAC,MAAM,EAAE,MAAM,EAAC,GAAG,MAAM,IAAI,CAAC,mBAAmB,CAAC,GAAG,CAAC,IAAI,CAAC,CAAA;YAEjE,MAAM,CAAC,MAAM,CAAC,QAAQ,CAAC;gBACrB,GAAG,CAAC,CAAC,MAAM,IAAI,IAAI,GAAG,CAAC,IAAI,CAAC,CAAC,CAAC;oBAC5B,MAAM,CAAC,MAAM,CAAC,cAAc,CAAC,mBAAW,CAAC,IAAI,CAAC,EAAE,OAAO,CAAC,CAAA;gBAC1D,CAAC;YACH,CAAC,CAAC,CAAA;YAEF,EAAE,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC;gBACZ,MAAM,CAAC,MAAM,CAAC,IAAI,EAAE,CAAA;gBACpB,MAAM,CAAC,EAAE,CAAC,OAAO,EAAE;oBACjB,MAAM,CAAC,MAAM,CAAC,OAAO,EAAE,CAAA;gBACzB,CAAC,CAAC,CAAA;YACJ,CAAC;QACH,CAAC,CAAA,CAAC,CAAA;IACJ,CAAC,CAAA,CAAA;AACH,CAAC,CAAC,CAAA"} \ No newline at end of file diff --git a/dist/main/atom/components/componentRegistry.js b/dist/main/atom/components/componentRegistry.js deleted file mode 100644 index d2905b34c..000000000 --- a/dist/main/atom/components/componentRegistry.js +++ /dev/null @@ -1,5 +0,0 @@ -"use strict"; -function __export(m) { - for (var p in m) if (!exports.hasOwnProperty(p)) exports[p] = m[p]; -} -__export(require("./ts-view")); diff --git a/dist/main/atom/components/index.js b/dist/main/atom/components/index.js new file mode 100644 index 000000000..46b6f9c81 --- /dev/null +++ b/dist/main/atom/components/index.js @@ -0,0 +1,7 @@ +"use strict"; +function __export(m) { + for (var p in m) if (!exports.hasOwnProperty(p)) exports[p] = m[p]; +} +Object.defineProperty(exports, "__esModule", { value: true }); +__export(require("./tsView")); +//# sourceMappingURL=index.js.map \ No newline at end of file diff --git a/dist/main/atom/components/index.js.map b/dist/main/atom/components/index.js.map new file mode 100644 index 000000000..f0757407a --- /dev/null +++ b/dist/main/atom/components/index.js.map @@ -0,0 +1 @@ +{"version":3,"file":"index.js","sourceRoot":"","sources":["../../../../lib/main/atom/components/index.ts"],"names":[],"mappings":";;;;;AAAA,8BAAyB"} \ No newline at end of file diff --git a/dist/main/atom/components/statusPanel.js b/dist/main/atom/components/statusPanel.js new file mode 100644 index 000000000..5790abf96 --- /dev/null +++ b/dist/main/atom/components/statusPanel.js @@ -0,0 +1,125 @@ +"use strict"; +Object.defineProperty(exports, "__esModule", { value: true }); +const dom = require("jsx-render-dom"); +const path_1 = require("path"); +const utils_1 = require("../utils"); +class StatusPanel extends HTMLElement { + createdCallback() { + const nodes = [ + dom.createElement("div", { ref: el => this.version = el, className: "inline-block" }), + dom.createElement("a", { ref: el => this.pendingContainer = el, className: "inline-block", href: "", onClick: evt => { + evt.preventDefault(); + this.showPendingRequests(); + } }, + dom.createElement("span", { ref: span => this.pendingCounter = span }), + dom.createElement("span", { ref: span => this.pendingSpinner = span, className: "loading loading-spinner-tiny inline-block", style: { marginLeft: "5px", opacity: 0.5, verticalAlign: "sub" } })), + dom.createElement("a", { ref: el => this.configPathContainer = el, className: "inline-block", href: "", onClick: evt => { + evt.preventDefault(); + this.openConfigPath(); + } }), + dom.createElement("div", { ref: el => this.statusContainer = el, className: "inline-block" }, + dom.createElement("span", { ref: el => this.statusText = el })), + dom.createElement("progress", { ref: el => this.progress = el, style: { verticalAlign: "baseline" }, className: 'inline-block' }) + ]; + for (const node of nodes) { + this.appendChild(node); + } + this.setVersion(undefined); + this.setPending([], true); + this.setTsConfigPath(undefined); + this.setBuildStatus(undefined); + this.setProgress(undefined); + } + dispose() { + this.remove(); + } + openConfigPath() { + if (this.configPath && !this.configPath.startsWith("/dev/null")) { + utils_1.openFile(this.configPath); + } + else { + atom.notifications.addInfo("No tsconfig for current file"); + } + } + setBuildStatus(status) { + const container = this.statusText; + if (status) { + if (status.success) { + container.classList.remove("highlight-error"); + container.classList.add("highlight-success"); + container.textContent = "Emit Success"; + } + else { + container.classList.add("highlight-error"); + container.classList.remove("highlight-success"); + container.textContent = "Emit Failed"; + } + this.statusContainer.classList.remove("hide"); + } + else { + this.statusContainer.classList.add("hide"); + } + } + setProgress(progress) { + if (progress) { + this.progress.max = progress.max; + this.progress.value = progress.value; + this.progress.classList.remove("hide"); + } + else { + this.progress.classList.add("hide"); + } + } + setTsConfigPath(configPath) { + this.configPath = configPath; + if (configPath) { + this.configPathContainer.textContent = configPath.startsWith("/dev/null") ? "No project" : + path_1.dirname(utils_1.getFilePathRelativeToAtomProject(configPath)); + this.configPathContainer.classList.remove("hide"); + } + else { + this.configPathContainer.classList.add("hide"); + } + } + setVersion(version) { + if (version) { + this.version.textContent = version; + this.version.classList.remove("hide"); + } + else { + this.version.classList.add("hide"); + } + } + _setPending(pending) { + this.pendingRequests = pending; + if (pending.length) { + this.pendingContainer.classList.remove("hide"); + this.pendingCounter.textContent = pending.length.toString(); + } + else { + this.pendingContainer.classList.add("hide"); + } + } + setPending(pending, immediate = false) { + const timeout = immediate ? 0 : 100; + clearTimeout(this.pendingTimeout); + this.pendingTimeout = setTimeout(() => this._setPending(pending), timeout); + } + showPendingRequests() { + if (this.pendingRequests) { + atom.notifications.addInfo("Pending Requests:
- " + this.pendingRequests.join("
- ")); + } + } + show() { + this.classList.remove("hide"); + } + hide() { + this.classList.add("hide"); + } + static create() { + return document.createElement("ts-status-panel"); + } +} +exports.StatusPanel = StatusPanel; +document.registerElement('ts-status-panel', StatusPanel); +//# sourceMappingURL=statusPanel.js.map \ No newline at end of file diff --git a/dist/main/atom/components/statusPanel.js.map b/dist/main/atom/components/statusPanel.js.map new file mode 100644 index 000000000..a078bf2de --- /dev/null +++ b/dist/main/atom/components/statusPanel.js.map @@ -0,0 +1 @@ +{"version":3,"file":"statusPanel.js","sourceRoot":"","sources":["../../../../lib/main/atom/components/statusPanel.tsx"],"names":[],"mappings":";;AAAA,sCAAqC;AACrC,+BAA4B;AAC5B,oCAGiB;AAEjB,iBAAyB,SAAQ,WAAW;IAe1C,eAAe;QACb,MAAM,KAAK,GAAG;YACZ,2BAAK,GAAG,EAAG,EAAE,IAAI,IAAI,CAAC,OAAO,GAAG,EAAE,EAAG,SAAS,EAAC,cAAc,GAAG;YAChE,yBAAG,GAAG,EAAG,EAAE,IAAI,IAAI,CAAC,gBAAgB,GAAG,EAAE,EACvC,SAAS,EAAC,cAAc,EACxB,IAAI,EAAC,EAAE,EACP,OAAO,EAAG,GAAG;oBACX,GAAG,CAAC,cAAc,EAAE,CAAA;oBACpB,IAAI,CAAC,mBAAmB,EAAE,CAAA;gBAC5B,CAAC;gBACD,4BAAM,GAAG,EAAG,IAAI,IAAI,IAAI,CAAC,cAAc,GAAG,IAAI,GAAU;gBACxD,4BAAM,GAAG,EAAG,IAAI,IAAI,IAAI,CAAC,cAAc,GAAG,IAAI,EAC5C,SAAS,EAAC,2CAA2C,EACrD,KAAK,EAAE,EAAC,UAAU,EAAE,KAAK,EAAE,OAAO,EAAE,GAAG,EAAE,aAAa,EAAE,KAAK,EAAC,GACzD,CACL;YACJ,yBAAG,GAAG,EAAG,EAAE,IAAI,IAAI,CAAC,mBAAmB,GAAG,EAAE,EAC1C,SAAS,EAAC,cAAc,EACxB,IAAI,EAAC,EAAE,EACP,OAAO,EAAG,GAAG;oBACX,GAAG,CAAC,cAAc,EAAE,CAAA;oBACpB,IAAI,CAAC,cAAc,EAAE,CAAA;gBACvB,CAAC,GAAG;YACN,2BAAK,GAAG,EAAG,EAAE,IAAI,IAAI,CAAC,eAAe,GAAG,EAAE,EACxC,SAAS,EAAC,cAAc;gBACxB,4BAAM,GAAG,EAAG,EAAE,IAAI,IAAI,CAAC,UAAU,GAAG,EAAE,GAAK,CACvC;YACN,gCAAU,GAAG,EAAG,EAAE,IAAI,IAAI,CAAC,QAAQ,GAAG,EAAE,EACtC,KAAK,EAAE,EAAE,aAAa,EAAE,UAAU,EAAE,EACpC,SAAS,EAAC,cAAc,GAAG;SAC9B,CAAA;QAED,GAAG,CAAC,CAAC,MAAM,IAAI,IAAI,KAAK,CAAC,CAAC,CAAC;YACzB,IAAI,CAAC,WAAW,CAAC,IAAI,CAAC,CAAA;QACxB,CAAC;QAED,IAAI,CAAC,UAAU,CAAC,SAAS,CAAC,CAAA;QAC1B,IAAI,CAAC,UAAU,CAAC,EAAE,EAAE,IAAI,CAAC,CAAA;QACzB,IAAI,CAAC,eAAe,CAAC,SAAS,CAAC,CAAA;QAC/B,IAAI,CAAC,cAAc,CAAC,SAAS,CAAC,CAAA;QAC9B,IAAI,CAAC,WAAW,CAAC,SAAS,CAAC,CAAA;IAC7B,CAAC;IAED,OAAO;QACL,IAAI,CAAC,MAAM,EAAE,CAAA;IACf,CAAC;IAED,cAAc;QACZ,EAAE,CAAC,CAAC,IAAI,CAAC,UAAU,IAAI,CAAC,IAAI,CAAC,UAAU,CAAC,UAAU,CAAC,WAAW,CAAC,CAAC,CAAC,CAAC;YAChE,gBAAQ,CAAC,IAAI,CAAC,UAAU,CAAC,CAAA;QAC3B,CAAC;QAAC,IAAI,CAAC,CAAC;YACN,IAAI,CAAC,aAAa,CAAC,OAAO,CAAC,8BAA8B,CAAC,CAAA;QAC5D,CAAC;IACH,CAAC;IAED,cAAc,CAAC,MAA2B;QACxC,MAAM,SAAS,GAAG,IAAI,CAAC,UAAU,CAAA;QACjC,EAAE,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC;YACX,EAAE,CAAC,CAAC,MAAM,CAAC,OAAO,CAAC,CAAC,CAAC;gBACnB,SAAS,CAAC,SAAS,CAAC,MAAM,CAAC,iBAAiB,CAAC,CAAA;gBAC7C,SAAS,CAAC,SAAS,CAAC,GAAG,CAAC,mBAAmB,CAAC,CAAA;gBAC5C,SAAS,CAAC,WAAW,GAAG,cAAc,CAAA;YACxC,CAAC;YAAC,IAAI,CAAC,CAAC;gBACN,SAAS,CAAC,SAAS,CAAC,GAAG,CAAC,iBAAiB,CAAC,CAAA;gBAC1C,SAAS,CAAC,SAAS,CAAC,MAAM,CAAC,mBAAmB,CAAC,CAAA;gBAC/C,SAAS,CAAC,WAAW,GAAG,aAAa,CAAA;YACvC,CAAC;YACD,IAAI,CAAC,eAAe,CAAC,SAAS,CAAC,MAAM,CAAC,MAAM,CAAC,CAAA;QAC/C,CAAC;QAAC,IAAI,CAAC,CAAC;YACN,IAAI,CAAC,eAAe,CAAC,SAAS,CAAC,GAAG,CAAC,MAAM,CAAC,CAAA;QAC5C,CAAC;IACH,CAAC;IAED,WAAW,CAAC,QAAuC;QACjD,EAAE,CAAC,CAAC,QAAQ,CAAC,CAAC,CAAC;YACb,IAAI,CAAC,QAAQ,CAAC,GAAG,GAAG,QAAQ,CAAC,GAAG,CAAA;YAChC,IAAI,CAAC,QAAQ,CAAC,KAAK,GAAG,QAAQ,CAAC,KAAK,CAAA;YACpC,IAAI,CAAC,QAAQ,CAAC,SAAS,CAAC,MAAM,CAAC,MAAM,CAAC,CAAA;QACxC,CAAC;QAAC,IAAI,CAAC,CAAC;YACN,IAAI,CAAC,QAAQ,CAAC,SAAS,CAAC,GAAG,CAAC,MAAM,CAAC,CAAA;QACrC,CAAC;IACH,CAAC;IAED,eAAe,CAAC,UAAmB;QACjC,IAAI,CAAC,UAAU,GAAG,UAAU,CAAA;QAE5B,EAAE,CAAC,CAAC,UAAU,CAAC,CAAC,CAAC;YACf,IAAI,CAAC,mBAAmB,CAAC,WAAW,GAAG,UAAU,CAAC,UAAU,CAAC,WAAW,CAAC,GAAG,YAAY;gBACtF,cAAO,CAAC,wCAAgC,CAAC,UAAU,CAAC,CAAC,CAAA;YAEvD,IAAI,CAAC,mBAAmB,CAAC,SAAS,CAAC,MAAM,CAAC,MAAM,CAAC,CAAA;QACnD,CAAC;QAAC,IAAI,CAAC,CAAC;YACN,IAAI,CAAC,mBAAmB,CAAC,SAAS,CAAC,GAAG,CAAC,MAAM,CAAC,CAAA;QAChD,CAAC;IACH,CAAC;IAED,UAAU,CAAC,OAAgB;QACzB,EAAE,CAAC,CAAC,OAAO,CAAC,CAAC,CAAC;YACZ,IAAI,CAAC,OAAO,CAAC,WAAW,GAAG,OAAO,CAAA;YAClC,IAAI,CAAC,OAAO,CAAC,SAAS,CAAC,MAAM,CAAC,MAAM,CAAC,CAAA;QACvC,CAAC;QAAC,IAAI,CAAC,CAAC;YACN,IAAI,CAAC,OAAO,CAAC,SAAS,CAAC,GAAG,CAAC,MAAM,CAAC,CAAA;QACpC,CAAC;IACH,CAAC;IAEO,WAAW,CAAC,OAAiB;QACnC,IAAI,CAAC,eAAe,GAAG,OAAO,CAAA;QAE9B,EAAE,CAAC,CAAC,OAAO,CAAC,MAAM,CAAC,CAAC,CAAC;YACnB,IAAI,CAAC,gBAAgB,CAAC,SAAS,CAAC,MAAM,CAAC,MAAM,CAAC,CAAA;YAC9C,IAAI,CAAC,cAAc,CAAC,WAAW,GAAG,OAAO,CAAC,MAAM,CAAC,QAAQ,EAAE,CAAA;QAC7D,CAAC;QAAC,IAAI,CAAC,CAAC;YACN,IAAI,CAAC,gBAAgB,CAAC,SAAS,CAAC,GAAG,CAAC,MAAM,CAAC,CAAA;QAC7C,CAAC;IACH,CAAC;IAED,UAAU,CAAC,OAAiB,EAAE,SAAS,GAAG,KAAK;QAC7C,MAAM,OAAO,GAAG,SAAS,GAAG,CAAC,GAAG,GAAG,CAAA;QACnC,YAAY,CAAC,IAAI,CAAC,cAAc,CAAC,CAAA;QACjC,IAAI,CAAC,cAAc,GAAG,UAAU,CAAC,MAAM,IAAI,CAAC,WAAW,CAAC,OAAO,CAAC,EAAE,OAAO,CAAC,CAAA;IAC5E,CAAC;IAED,mBAAmB;QACjB,EAAE,CAAC,CAAC,IAAI,CAAC,eAAe,CAAC,CAAC,CAAC;YACzB,IAAI,CAAC,aAAa,CAAC,OAAO,CAAC,4BAA4B,GAAG,IAAI,CAAC,eAAe,CAAC,IAAI,CAAC,UAAU,CAAC,CAAC,CAAA;QAClG,CAAC;IACH,CAAC;IAED,IAAI;QACF,IAAI,CAAC,SAAS,CAAC,MAAM,CAAC,MAAM,CAAC,CAAA;IAC/B,CAAC;IAED,IAAI;QACF,IAAI,CAAC,SAAS,CAAC,GAAG,CAAC,MAAM,CAAC,CAAA;IAC5B,CAAC;IAED,MAAM,CAAC,MAAM;QACX,MAAM,CAAC,QAAQ,CAAC,aAAa,CAAC,iBAAiB,CAAgB,CAAA;IACjE,CAAC;CACF;AA1JD,kCA0JC;AAEA,QAAgB,CAAC,eAAe,CAAC,iBAAiB,EAAE,WAAW,CAAC,CAAA"} \ No newline at end of file diff --git a/dist/main/atom/components/ts-view.js b/dist/main/atom/components/tsView.js similarity index 53% rename from dist/main/atom/components/ts-view.js rename to dist/main/atom/components/tsView.js index d8916aee8..e6fe6b56b 100644 --- a/dist/main/atom/components/ts-view.js +++ b/dist/main/atom/components/tsView.js @@ -1,32 +1,29 @@ +// Some docs +// http://www.html5rocks.com/en/tutorials/webcomponents/customelements/ (look at lifecycle callback methods) "use strict"; -var __extends = (this && this.__extends) || function (d, b) { - for (var p in b) if (b.hasOwnProperty(p)) d[p] = b[p]; - function __() { this.constructor = d; } - d.prototype = b === null ? Object.create(b) : (__.prototype = b.prototype, new __()); -}; -var TsView = (function (_super) { - __extends(TsView, _super); - function TsView() { - return _super.apply(this, arguments) || this; - } - TsView.prototype.createdCallback = function () { +Object.defineProperty(exports, "__esModule", { value: true }); +class TsView extends HTMLElement { + createdCallback() { var preview = this.innerText; this.innerText = ""; + // Based on markdown editor + // https://github.com/atom/markdown-preview/blob/2bcbadac3980f1aeb455f7078bd1fdfb4e6fe6b1/lib/renderer.coffee#L111 var editorElement = this.editorElement = document.createElement('atom-text-editor'); editorElement.setAttributeNode(document.createAttribute('gutter-hidden')); - editorElement.removeAttribute('tabindex'); + editorElement.removeAttribute('tabindex'); // make read-only var editor = this.editor = editorElement.getModel(); - editor.getDecorations({ class: 'cursor-line', type: 'line' })[0].destroy(); + editor.getDecorations({ class: 'cursor-line', type: 'line' })[0].destroy(); // remove the default selection of a line in each editor editor.setText(preview); var grammar = atom.grammars.grammarForScopeName("source.tsx"); editor.setGrammar(grammar); editor.setSoftWrapped(true); this.appendChild(editorElement); - }; - TsView.prototype.text = function (text) { + } + // API + text(text) { this.editor.setText(text); - }; - return TsView; -}(HTMLElement)); + } +} exports.TsView = TsView; document.registerElement('ts-view', TsView); +//# sourceMappingURL=tsView.js.map \ No newline at end of file diff --git a/dist/main/atom/components/tsView.js.map b/dist/main/atom/components/tsView.js.map new file mode 100644 index 000000000..6184b4bfe --- /dev/null +++ b/dist/main/atom/components/tsView.js.map @@ -0,0 +1 @@ +{"version":3,"file":"tsView.js","sourceRoot":"","sources":["../../../../lib/main/atom/components/tsView.ts"],"names":[],"mappings":"AAAA,YAAY;AACZ,4GAA4G;;;AAE5G,YAAoB,SAAQ,WAAW;IAGnC,eAAe;QACX,IAAI,OAAO,GAAG,IAAI,CAAC,SAAS,CAAC;QAC7B,IAAI,CAAC,SAAS,GAAG,EAAE,CAAC;QAEpB,2BAA2B;QAC3B,kHAAkH;QAClH,IAAI,aAAa,GAAG,IAAI,CAAC,aAAa,GAAG,QAAQ,CAAC,aAAa,CAAC,kBAAkB,CAAC,CAAC;QACpF,aAAa,CAAC,gBAAgB,CAAC,QAAQ,CAAC,eAAe,CAAC,eAAe,CAAC,CAAC,CAAC;QAC1E,aAAa,CAAC,eAAe,CAAC,UAAU,CAAC,CAAC,CAAC,iBAAiB;QAC5D,IAAI,MAAM,GAAG,IAAI,CAAC,MAAM,GAAS,aAAc,CAAC,QAAQ,EAAE,CAAC;QAC3D,MAAM,CAAC,cAAc,CAAC,EAAE,KAAK,EAAE,aAAa,EAAE,IAAI,EAAE,MAAM,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,OAAO,EAAE,CAAC,CAAC,wDAAwD;QACpI,MAAM,CAAC,OAAO,CAAC,OAAO,CAAC,CAAC;QACxB,IAAI,OAAO,GAAS,IAAK,CAAC,QAAQ,CAAC,mBAAmB,CAAC,YAAY,CAAC,CAAA;QACpE,MAAM,CAAC,UAAU,CAAC,OAAO,CAAC,CAAC;QAC3B,MAAM,CAAC,cAAc,CAAC,IAAI,CAAC,CAAC;QAE5B,IAAI,CAAC,WAAW,CAAC,aAAa,CAAC,CAAC;IACpC,CAAC;IAED,MAAM;IACN,IAAI,CAAC,IAAY;QACb,IAAI,CAAC,MAAM,CAAC,OAAO,CAAC,IAAI,CAAC,CAAC;IAC9B,CAAC;CACJ;AA1BD,wBA0BC;AAEK,QAAS,CAAC,eAAe,CAAC,SAAS,EAAE,MAAM,CAAC,CAAC"} \ No newline at end of file diff --git a/dist/main/atom/debugAtomTs.js b/dist/main/atom/debugAtomTs.js deleted file mode 100644 index ffffdfa76..000000000 --- a/dist/main/atom/debugAtomTs.js +++ /dev/null @@ -1,7 +0,0 @@ -"use strict"; -var atomConfig = require("./atomConfig"); -function runDebugCode(details) { - if (!atomConfig.debugAtomTs) - return; -} -exports.runDebugCode = runDebugCode; diff --git a/dist/main/atom/editorSetup.js b/dist/main/atom/editorSetup.js index 9e755204d..831f477d2 100644 --- a/dist/main/atom/editorSetup.js +++ b/dist/main/atom/editorSetup.js @@ -1,4 +1,65 @@ "use strict"; +Object.defineProperty(exports, "__esModule", { value: true }); function setupEditor(editor) { + const editorView = atom.views.getView(editor); + // Add and remove 'typescript-editor' class from the + // where typescript is active. + editorView.classList.add('typescript-editor'); + editor.onDidDestroy(() => { + editorView.classList.remove('typescript-editor'); + }); + // + // // Quick fix decoration stuff + // var quickFixDecoration: AtomCore.Decoration = null; + // var quickFixMarker: any = null; + // function clearExistingQuickfixDecoration() { + // if (quickFixDecoration) { + // quickFixDecoration.destroy(); + // quickFixDecoration = null; + // } + // if (quickFixMarker) { + // quickFixMarker.destroy(); + // quickFixMarker = null; + // } + // } + // var queryForQuickFix = debounce((filePathPosition:{filePath:string;position:number}) => { + // parent.getQuickFixes(filePathPosition).then(res=> { + // clearExistingQuickfixDecoration(); + // if (res.fixes.length) { + // quickFixMarker = editor.markBufferRange(editor.getSelectedBufferRange()); + // quickFixDecoration = editor.decorateMarker(quickFixMarker, + // { type: "line-number", class: "quickfix" }); + // } + // }) + // }, 500); + // var cursorObserver = editor.onDidChangeCursorPosition(() => { + // try { + // // This line seems to throw an exception sometimes. + // // https://github.com/TypeStrong/atom-typescript/issues/325 + // // https://github.com/TypeStrong/atom-typescript/issues/310 + // let pathPos = atomUtils.getFilePathPosition(); + // + // // TODO: implement quickfix logic for transformed files + // if (isTransformerFile(pathPos.filePath)) { + // clearExistingQuickfixDecoration(); + // return; + // } + // + // queryForQuickFix(pathPos); + // } + // catch (ex) { + // clearExistingQuickfixDecoration(); + // } + // }); + // + // + // /** + // * On final dispose + // */ + // var destroyObserver = editor.onDidDestroy(() => { + // // Clear editor observers + // cursorObserver.dispose(); + // destroyObserver.dispose(); + // }); } exports.setupEditor = setupEditor; diff --git a/dist/main/atom/fileStatusCache.js b/dist/main/atom/fileStatusCache.js deleted file mode 100644 index e5fa82b07..000000000 --- a/dist/main/atom/fileStatusCache.js +++ /dev/null @@ -1,12 +0,0 @@ -"use strict"; -var fsUtil_1 = require("../utils/fsUtil"); -; -var fileStatuses = {}; -function getFileStatus(filePath) { - filePath = fsUtil_1.consistentPath(filePath); - if (!fileStatuses[filePath]) { - fileStatuses[filePath] = { modified: false, emitDiffers: false }; - } - return fileStatuses[filePath]; -} -exports.getFileStatus = getFileStatus; diff --git a/dist/main/atom/gotoHistory.js b/dist/main/atom/gotoHistory.js deleted file mode 100644 index acb6dbf9c..000000000 --- a/dist/main/atom/gotoHistory.js +++ /dev/null @@ -1,68 +0,0 @@ -"use strict"; -exports.errorsInOpenFiles = { members: [] }; -exports.buildOutput = { members: [] }; -exports.referencesOutput = { members: [] }; -exports.activeList = exports.errorsInOpenFiles; -function gotoLine(filePath, line, col, list) { - var activeFile, activeEditor = atom.workspace.getActiveTextEditor(); - if (activeEditor !== undefined && activeEditor !== null) { - activeFile = activeEditor.getPath(); - } - if (filePath !== activeFile) { - atom.workspace.open(filePath, { - initialLine: line - 1, - initialColumn: col - }); - } - else { - atom.workspace.getActiveTextEditor().cursors[0].setBufferPosition([line - 1, col]); - } - list.lastPosition = { filePath: filePath, line: line, col: col }; -} -exports.gotoLine = gotoLine; -function findCurrentIndexInList() { - if (!exports.activeList.members.length) { - atom.notifications.addInfo('AtomTS: no go-to members in active list'); - return -1; - } - if (!exports.activeList.lastPosition) - return 0; - var lastPosition = exports.activeList.lastPosition; - var index = indexOf(exports.activeList.members, function (item) { return item.filePath == lastPosition.filePath && item.line == lastPosition.line; }); - if (index == -1) { - return 0; - } - return index; -} -function gotoNext() { - var currentIndex = findCurrentIndexInList(); - if (currentIndex == -1) - return; - var nextIndex = currentIndex + 1; - if (nextIndex == exports.activeList.members.length) { - nextIndex = 0; - } - var next = exports.activeList.members[nextIndex]; - gotoLine(next.filePath, next.line, next.col, exports.activeList); -} -exports.gotoNext = gotoNext; -function gotoPrevious() { - var currentIndex = findCurrentIndexInList(); - if (currentIndex == -1) - return; - var previousIndex = currentIndex - 1; - if (previousIndex == -1) { - previousIndex = exports.activeList.members.length - 1; - } - var previous = exports.activeList.members[previousIndex]; - gotoLine(previous.filePath, previous.line, previous.col, exports.activeList); -} -exports.gotoPrevious = gotoPrevious; -function indexOf(items, filter) { - for (var i = 0; i < items.length; i++) { - if (filter(items[i])) { - return i; - } - } - return -1; -} diff --git a/dist/main/atom/onSaveHandler.js b/dist/main/atom/onSaveHandler.js deleted file mode 100644 index 03d0e4613..000000000 --- a/dist/main/atom/onSaveHandler.js +++ /dev/null @@ -1,35 +0,0 @@ -"use strict"; -var atomUtils = require("./atomUtils"); -var parent = require("../../worker/parent"); -var mainPanelView_1 = require("./views/mainPanelView"); -var fileStatusCache_1 = require("./fileStatusCache"); -function handle(event) { - var textUpdated = parent.updateText({ filePath: event.filePath, text: event.editor.getText() }); - textUpdated.then(function () { - atomUtils.triggerLinter(); - parent.errorsForFile({ filePath: event.filePath }) - .then(function (resp) { return mainPanelView_1.errorView.setErrors(event.filePath, resp.errors); }); - }); - mainPanelView_1.show(); - parent.getProjectFileDetails({ filePath: event.filePath }).then(function (fileDetails) { - if (fileDetails.project.compileOnSave - && !fileDetails.project.compilerOptions.outFile - && !fileDetails.project.buildOnSave) { - textUpdated.then(function () { return parent.emitFile({ filePath: event.filePath }); }) - .then(function (res) { - var status = fileStatusCache_1.getFileStatus(event.filePath); - status.modified = false; - status.emitDiffers = res.emitError; - mainPanelView_1.panelView.updateFileStatus(event.filePath); - mainPanelView_1.errorView.showEmittedMessage(res); - }); - } - if (fileDetails.project.buildOnSave) { - atom.commands.dispatch(atom.views.getView(event.editor), 'typescript:build'); - } - if (fileDetails.project.atom.formatOnSave) { - atom.commands.dispatch(atom.views.getView(event.editor), 'typescript:format-code'); - } - }); -} -exports.handle = handle; diff --git a/dist/main/atom/signatureProvider.js b/dist/main/atom/signatureProvider.js deleted file mode 100644 index df09737c2..000000000 --- a/dist/main/atom/signatureProvider.js +++ /dev/null @@ -1,4 +0,0 @@ -"use strict"; -function requestHandler(config) { -} -exports.requestHandler = requestHandler; diff --git a/dist/main/atom/tooltipManager.js b/dist/main/atom/tooltipManager.js index b98e948fc..afa4f63af 100644 --- a/dist/main/atom/tooltipManager.js +++ b/dist/main/atom/tooltipManager.js @@ -1,14 +1,18 @@ +// Inspiration : https://atom.io/packages/ide-haskell +// and https://atom.io/packages/ide-flow "use strict"; -var atomUtils = require("./atomUtils"); -var parent = require("../../worker/parent"); -var path = require("path"); -var fs = require("fs"); -var emissary = require("emissary"); +Object.defineProperty(exports, "__esModule", { value: true }); +const tslib_1 = require("tslib"); +const atomUtils = require("./utils"); ///ts:import:generated +const atomts_1 = require("../atomts"); +const path = require("path"); +const fs = require("fs"); +const emissary = require("emissary"); var Subscriber = emissary.Subscriber; -var tooltipView = require("./views/tooltipView"); +const tooltipView = require("./views/tooltipView"); var TooltipView = tooltipView.TooltipView; -var atom_space_pen_views_1 = require("atom-space-pen-views"); -var escape = require("escape-html"); +const atom_space_pen_views_1 = require("atom-space-pen-views"); +const escape = require("escape-html"); function getFromShadowDom(element, selector) { var el = element[0]; var found = el.rootElement.querySelectorAll(selector); @@ -17,65 +21,79 @@ function getFromShadowDom(element, selector) { exports.getFromShadowDom = getFromShadowDom; function attach(editorView, editor) { var rawView = editorView[0]; + // Only on ".ts" files var filePath = editor.getPath(); + if (!filePath) { + return; + } var filename = path.basename(filePath); var ext = path.extname(filename); if (!atomUtils.isAllowedExtension(ext)) return; + // We only create a "program" once the file is persisted to disk if (!fs.existsSync(filePath)) { return; } + var clientPromise = atomts_1.clientResolver.get(filePath); var scroll = getFromShadowDom(editorView, '.scroll-view'); var subscriber = new Subscriber(); - var exprTypeTimeout = null; - var exprTypeTooltip = null; + var exprTypeTimeout; + var exprTypeTooltip; + // to debounce mousemove event's firing for some reason on some machines var lastExprTypeBufferPt; - subscriber.subscribe(scroll, 'mousemove', function (e) { + subscriber.subscribe(scroll, 'mousemove', (e) => { var pixelPt = pixelPositionFromMouseEvent(editorView, e); - var screenPt = editor.screenPositionForPixelPosition(pixelPt); + var screenPt = editor.element.screenPositionForPixelPosition(pixelPt); var bufferPt = editor.bufferPositionForScreenPosition(screenPt); if (lastExprTypeBufferPt && lastExprTypeBufferPt.isEqual(bufferPt) && exprTypeTooltip) return; lastExprTypeBufferPt = bufferPt; clearExprTypeTimeout(); - exprTypeTimeout = setTimeout(function () { return showExpressionType(e); }, 100); + exprTypeTimeout = setTimeout(() => showExpressionType(e), 100); }); - subscriber.subscribe(scroll, 'mouseout', function (e) { return clearExprTypeTimeout(); }); - subscriber.subscribe(scroll, 'keydown', function (e) { return clearExprTypeTimeout(); }); - editor.onDidDestroy(function () { return deactivate(); }); + subscriber.subscribe(scroll, 'mouseout', () => clearExprTypeTimeout()); + subscriber.subscribe(scroll, 'keydown', () => clearExprTypeTimeout()); + // Setup for clearing + editor.onDidDestroy(() => deactivate()); function showExpressionType(e) { - if (exprTypeTooltip) - return; - var pixelPt = pixelPositionFromMouseEvent(editorView, e); - pixelPt.top += editor.getScrollTop(); - pixelPt.left += editor.getScrollLeft(); - var screenPt = editor.screenPositionForPixelPosition(pixelPt); - var bufferPt = editor.bufferPositionForScreenPosition(screenPt); - var curCharPixelPt = rawView.pixelPositionForBufferPosition([bufferPt.row, bufferPt.column]); - var nextCharPixelPt = rawView.pixelPositionForBufferPosition([bufferPt.row, bufferPt.column + 1]); - if (curCharPixelPt.left >= nextCharPixelPt.left) - return; - var offset = editor.getLineHeightInPixels() * 0.7; - var tooltipRect = { - left: e.clientX, - right: e.clientX, - top: e.clientY - offset, - bottom: e.clientY + offset - }; - exprTypeTooltip = new TooltipView(tooltipRect); - var position = atomUtils.getEditorPositionForBufferPosition(editor, bufferPt); - parent.quickInfo({ filePath: filePath, position: position }).then(function (resp) { - if (!resp.valid) { - hideExpressionType(); + return tslib_1.__awaiter(this, void 0, void 0, function* () { + // If we are already showing we should wait for that to clear + if (exprTypeTooltip) + return; + var pixelPt = pixelPositionFromMouseEvent(editorView, e); + pixelPt.top += editor.element.getScrollTop(); + pixelPt.left += editor.element.getScrollLeft(); + var screenPt = editor.element.screenPositionForPixelPosition(pixelPt); + var bufferPt = editor.bufferPositionForScreenPosition(screenPt); + var curCharPixelPt = rawView.pixelPositionForBufferPosition([bufferPt.row, bufferPt.column]); + var nextCharPixelPt = rawView.pixelPositionForBufferPosition([bufferPt.row, bufferPt.column + 1]); + if (curCharPixelPt.left >= nextCharPixelPt.left) + return; + // find out show position + var offset = editor.getLineHeightInPixels() * 0.7; + var tooltipRect = { + left: e.clientX, + right: e.clientX, + top: e.clientY - offset, + bottom: e.clientY + offset + }; + exprTypeTooltip = new TooltipView(tooltipRect); + const client = yield clientPromise; + const result = yield client.executeQuickInfo({ + file: filePath, + line: bufferPt.row + 1, + offset: bufferPt.column + 1 + }).catch(err => undefined); + if (!result) { + return; } - else { - var message = "" + escape(resp.name) + ""; - if (resp.comment) { - message = message + ("
" + escape(resp.comment).replace(/(?:\r\n|\r|\n)/g, '
') + "
"); - } - if (exprTypeTooltip) { - exprTypeTooltip.updateText(message); - } + const { displayString, documentation } = result.body; + var message = `${escape(displayString)}`; + if (documentation) { + message = message + `
${escape(documentation).replace(/(?:\r\n|\r|\n)/g, '
')}
`; + } + if (exprTypeTooltip) { + exprTypeTooltip.updateText(message); } }); } @@ -83,6 +101,7 @@ function attach(editorView, editor) { subscriber.unsubscribe(); clearExprTypeTimeout(); } + /** clears the timeout && the tooltip */ function clearExprTypeTimeout() { if (exprTypeTimeout) { clearTimeout(exprTypeTimeout); @@ -94,7 +113,7 @@ function attach(editorView, editor) { if (!exprTypeTooltip) return; exprTypeTooltip.$.remove(); - exprTypeTooltip = null; + exprTypeTooltip = undefined; } } exports.attach = attach; @@ -105,6 +124,4 @@ function pixelPositionFromMouseEvent(editorView, event) { var left = clientX - linesClientRect.left; return { top: top, left: left }; } -function screenPositionFromMouseEvent(editorView, event) { - return editorView.getModel().screenPositionForPixelPosition(pixelPositionFromMouseEvent(editorView, event)); -} +//# sourceMappingURL=tooltipManager.js.map \ No newline at end of file diff --git a/dist/main/atom/tooltipManager.js.map b/dist/main/atom/tooltipManager.js.map new file mode 100644 index 000000000..65464d9e2 --- /dev/null +++ b/dist/main/atom/tooltipManager.js.map @@ -0,0 +1 @@ +{"version":3,"file":"tooltipManager.js","sourceRoot":"","sources":["../../../lib/main/atom/tooltipManager.ts"],"names":[],"mappings":"AAAA,qDAAqD;AACrD,wCAAwC;;;;AAExC,qCAAsC,CAAC,sBAAsB;AAC7D,sCAAwC;AAExC,6BAA8B;AAC9B,yBAA0B;AAC1B,qCAAsC;AACtC,IAAI,UAAU,GAAG,QAAQ,CAAC,UAAU,CAAC;AACrC,mDAAoD;AACpD,IAAO,WAAW,GAAG,WAAW,CAAC,WAAW,CAAC;AAC7C,+DAAuC;AACvC,sCAAuC;AAEvC,0BAAiC,OAAe,EAAE,QAAgB;IAC9D,IAAI,EAAE,GAAG,OAAO,CAAC,CAAC,CAAC,CAAC;IACpB,IAAI,KAAK,GAAU,EAAG,CAAC,WAAW,CAAC,gBAAgB,CAAC,QAAQ,CAAC,CAAC;IAC9D,MAAM,CAAC,wBAAC,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,CAAC;AACvB,CAAC;AAJD,4CAIC;AAED,gBAAuB,UAAkB,EAAE,MAAwB;IAC/D,IAAI,OAAO,GAAQ,UAAU,CAAC,CAAC,CAAC,CAAC;IAEjC,sBAAsB;IACtB,IAAI,QAAQ,GAAG,MAAM,CAAC,OAAO,EAAE,CAAC;IAChC,EAAE,CAAC,CAAC,CAAC,QAAQ,CAAC,CAAC,CAAC;QACd,MAAM,CAAC;IACT,CAAC;IACD,IAAI,QAAQ,GAAG,IAAI,CAAC,QAAQ,CAAC,QAAQ,CAAC,CAAC;IACvC,IAAI,GAAG,GAAG,IAAI,CAAC,OAAO,CAAC,QAAQ,CAAC,CAAC;IACjC,EAAE,CAAC,CAAC,CAAC,SAAS,CAAC,kBAAkB,CAAC,GAAG,CAAC,CAAC;QAAC,MAAM,CAAC;IAE/C,gEAAgE;IAChE,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC,UAAU,CAAC,QAAQ,CAAC,CAAC,CAAC,CAAC;QAC3B,MAAM,CAAC;IACX,CAAC;IAED,IAAI,aAAa,GAAG,uBAAc,CAAC,GAAG,CAAC,QAAQ,CAAC,CAAA;IAChD,IAAI,MAAM,GAAG,gBAAgB,CAAC,UAAU,EAAE,cAAc,CAAC,CAAC;IAC1D,IAAI,UAAU,GAAG,IAAI,UAAU,EAAE,CAAC;IAClC,IAAI,eAAgC,CAAC;IACrC,IAAI,eAAwC,CAAC;IAE7C,wEAAwE;IACxE,IAAI,oBAAyB,CAAC;IAE9B,UAAU,CAAC,SAAS,CAAC,MAAM,EAAE,WAAW,EAAE,CAAC,CAAa;QACpD,IAAI,OAAO,GAAG,2BAA2B,CAAC,UAAU,EAAE,CAAC,CAAC,CAAA;QACxD,IAAI,QAAQ,GAAG,MAAM,CAAC,OAAO,CAAC,8BAA8B,CAAC,OAAO,CAAC,CAAA;QACrE,IAAI,QAAQ,GAAG,MAAM,CAAC,+BAA+B,CAAC,QAAQ,CAAC,CAAA;QAC/D,EAAE,CAAC,CAAC,oBAAoB,IAAI,oBAAoB,CAAC,OAAO,CAAC,QAAQ,CAAC,IAAI,eAAe,CAAC;YAClF,MAAM,CAAC;QAEX,oBAAoB,GAAG,QAAQ,CAAC;QAEhC,oBAAoB,EAAE,CAAC;QACvB,eAAe,GAAG,UAAU,CAAC,MAAM,kBAAkB,CAAC,CAAC,CAAC,EAAE,GAAG,CAAC,CAAC;IACnE,CAAC,CAAC,CAAC;IACH,UAAU,CAAC,SAAS,CAAC,MAAM,EAAE,UAAU,EAAE,MAAM,oBAAoB,EAAE,CAAC,CAAC;IACvE,UAAU,CAAC,SAAS,CAAC,MAAM,EAAE,SAAS,EAAE,MAAM,oBAAoB,EAAE,CAAC,CAAC;IAEtE,qBAAqB;IACrB,MAAM,CAAC,YAAY,CAAC,MAAM,UAAU,EAAE,CAAC,CAAC;IAExC,4BAAkC,CAAa;;YAE3C,6DAA6D;YAC7D,EAAE,CAAC,CAAC,eAAe,CAAC;gBAAC,MAAM,CAAC;YAE5B,IAAI,OAAO,GAAG,2BAA2B,CAAC,UAAU,EAAE,CAAC,CAAC,CAAC;YACzD,OAAO,CAAC,GAAG,IAAI,MAAM,CAAC,OAAO,CAAC,YAAY,EAAE,CAAC;YAC7C,OAAO,CAAC,IAAI,IAAI,MAAM,CAAC,OAAO,CAAC,aAAa,EAAE,CAAC;YAC/C,IAAI,QAAQ,GAAG,MAAM,CAAC,OAAO,CAAC,8BAA8B,CAAC,OAAO,CAAC,CAAC;YACtE,IAAI,QAAQ,GAAG,MAAM,CAAC,+BAA+B,CAAC,QAAQ,CAAC,CAAC;YAChE,IAAI,cAAc,GAAG,OAAO,CAAC,8BAA8B,CAAC,CAAC,QAAQ,CAAC,GAAG,EAAE,QAAQ,CAAC,MAAM,CAAC,CAAC,CAAC;YAC7F,IAAI,eAAe,GAAG,OAAO,CAAC,8BAA8B,CAAC,CAAC,QAAQ,CAAC,GAAG,EAAE,QAAQ,CAAC,MAAM,GAAG,CAAC,CAAC,CAAC,CAAC;YAElG,EAAE,CAAC,CAAC,cAAc,CAAC,IAAI,IAAI,eAAe,CAAC,IAAI,CAAC;gBAAC,MAAM,CAAC;YAExD,yBAAyB;YACzB,IAAI,MAAM,GAAG,MAAM,CAAC,qBAAqB,EAAE,GAAG,GAAG,CAAC;YAClD,IAAI,WAAW,GAAG;gBACd,IAAI,EAAE,CAAC,CAAC,OAAO;gBACf,KAAK,EAAE,CAAC,CAAC,OAAO;gBAChB,GAAG,EAAE,CAAC,CAAC,OAAO,GAAG,MAAM;gBACvB,MAAM,EAAE,CAAC,CAAC,OAAO,GAAG,MAAM;aAC7B,CAAC;YACF,eAAe,GAAG,IAAI,WAAW,CAAC,WAAW,CAAC,CAAC;YAE/C,MAAM,MAAM,GAAG,MAAM,aAAa,CAAA;YAClC,MAAM,MAAM,GAAG,MAAM,MAAM,CAAC,gBAAgB,CAAC;gBACzC,IAAI,EAAE,QAAQ;gBACd,IAAI,EAAE,QAAQ,CAAC,GAAG,GAAC,CAAC;gBACpB,MAAM,EAAE,QAAQ,CAAC,MAAM,GAAC,CAAC;aAC5B,CAAC,CAAC,KAAK,CAAC,GAAG,IAAI,SAAS,CAAC,CAAA;YAE1B,EAAE,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC;gBACZ,MAAM,CAAA;YACR,CAAC;YAED,MAAM,EAAC,aAAa,EAAE,aAAa,EAAC,GAAG,MAAM,CAAC,IAAK,CAAA;YAEnD,IAAI,OAAO,GAAG,MAAM,MAAM,CAAC,aAAa,CAAE,MAAM,CAAC;YACjD,EAAE,CAAC,CAAC,aAAa,CAAC,CAAC,CAAC;gBAChB,OAAO,GAAG,OAAO,GAAG,WAAW,MAAM,CAAC,aAAa,CAAC,CAAC,OAAO,CAAC,iBAAiB,EAAE,QAAQ,CAAE,MAAM,CAAC;YACrG,CAAC;YACD,EAAE,CAAC,CAAC,eAAe,CAAC,CAAC,CAAC;gBACpB,eAAe,CAAC,UAAU,CAAC,OAAO,CAAC,CAAC;YACtC,CAAC;QACL,CAAC;KAAA;IAED;QACI,UAAU,CAAC,WAAW,EAAE,CAAC;QACzB,oBAAoB,EAAE,CAAC;IAC3B,CAAC;IACD,wCAAwC;IACxC;QACI,EAAE,CAAC,CAAC,eAAe,CAAC,CAAC,CAAC;YAClB,YAAY,CAAC,eAAe,CAAC,CAAC;YAC9B,eAAe,GAAG,IAAI,CAAC;QAC3B,CAAC;QACD,kBAAkB,EAAE,CAAC;IACzB,CAAC;IACD;QACI,EAAE,CAAC,CAAC,CAAC,eAAe,CAAC;YAAC,MAAM,CAAC;QAC7B,eAAe,CAAC,CAAC,CAAC,MAAM,EAAE,CAAC;QAC3B,eAAe,GAAG,SAAS,CAAC;IAChC,CAAC;AACL,CAAC;AA5GD,wBA4GC;AAGD,qCAAqC,UAAkB,EAAE,KAAiB;IACtE,IAAI,OAAO,GAAG,KAAK,CAAC,OAAO,EAAE,OAAO,GAAG,KAAK,CAAC,OAAO,CAAC;IACrD,IAAI,eAAe,GAAG,gBAAgB,CAAC,UAAU,EAAE,QAAQ,CAAC,CAAC,CAAC,CAAC,CAAC,qBAAqB,EAAE,CAAC;IACxF,IAAI,GAAG,GAAG,OAAO,GAAG,eAAe,CAAC,GAAG,CAAC;IACxC,IAAI,IAAI,GAAG,OAAO,GAAG,eAAe,CAAC,IAAI,CAAC;IAC1C,MAAM,CAAC,EAAE,GAAG,EAAE,GAAG,EAAE,IAAI,EAAE,IAAI,EAAE,CAAC;AACpC,CAAC"} \ No newline at end of file diff --git a/dist/main/atom/typescriptGrammar.js b/dist/main/atom/typescriptGrammar.js deleted file mode 100644 index 27f98b730..000000000 --- a/dist/main/atom/typescriptGrammar.js +++ /dev/null @@ -1,232 +0,0 @@ -"use strict"; -var __extends = (this && this.__extends) || function (d, b) { - for (var p in b) if (b.hasOwnProperty(p)) d[p] = b[p]; - function __() { this.constructor = d; } - d.prototype = b === null ? Object.create(b) : (__.prototype = b.prototype, new __()); -}; -var utils = require("../lang/utils"); -var TokenClass = ts.TokenClass; -global.AtomTSBaseGrammar = require(atom.config.resourcePath + "/node_modules/first-mate/lib/grammar.js"); -var TypeScriptSemanticGrammar = (function (_super) { - __extends(TypeScriptSemanticGrammar, _super); - function TypeScriptSemanticGrammar(registry) { - var _this = _super.call(this, registry, { - name: "TypeScript", - scopeName: "source.ts", - patterns: {}, - fileTypes: ['ts', 'tst'] - }) || this; - _this.registry = registry; - _this.trailingWhiteSpaceLength = 0; - _this.classifier = ts.createClassifier(); - _this.fullTripleSlashReferencePathRegEx = /^(\/\/\/\s*/; - _this.fullTripleSlashAMDNameRegEx = /^(\/\/\/\s*/; - _this.fullTripleSlashAMDDependencyPathRegEx = /^(\/\/\/\s*/; - _this.importRequireRegex = /^import\s*(\w*)\s*=\s*require\((?:'|")(\S*)(?:'|")\.*\)/; - _this.es6importRegex = /^import.*from.*/; - _this.todoRegex = new RegExp('(BUG|TODO|FIXME|CHANGED|XXX|IDEA|HACK|NOTE)'); - return _this; - } - TypeScriptSemanticGrammar.prototype.tokenizeLine = function (line, ruleStack, firstLine) { - if (firstLine === void 0) { firstLine = false; } - if (firstLine - && line.length > 1 - && (line.charCodeAt(0) == 0xFFFE || line.charCodeAt(0) == 0xFEFF)) { - this.trailingWhiteSpaceLength = 1; - } - else { - this.trailingWhiteSpaceLength = 0; - } - var finalLexState = firstLine ? ts.EndOfLineState.None - : ruleStack && ruleStack.length ? ruleStack[0] - : ts.EndOfLineState.None; - if (finalLexState !== ts.EndOfLineState.None) { - return this.getAtomTokensForLine(line, finalLexState); - } - if (line.match(this.fullTripleSlashReferencePathRegEx)) { - return this.getFullTripleSlashReferencePathTokensForLine(line); - } - else if (line.match(this.fullTripleSlashAMDNameRegEx)) { - return this.getFullTripleSlashAMDModuleNameTokensForLine(line); - } - else if (line.match(this.fullTripleSlashAMDDependencyPathRegEx)) { - return this.getFullTripleSlashAMDDependencyPathTokensForLine(line); - } - else if (line.match(this.importRequireRegex)) { - return this.getImportRequireTokensForLine(line); - } - else if (line.match(this.es6importRegex)) { - return this.getEs6importTokensForLine(line); - } - else { - return this.getAtomTokensForLine(line, finalLexState); - } - }; - TypeScriptSemanticGrammar.prototype.getFullTripleSlashTokensForLine = function (line, matches, argumentType) { - var tsTokensWithRuleStack = this.getTsTokensForLine(line); - if (matches[3]) { - var path = matches[3]; - if (line.indexOf('"' + path + '"') != -1) { - path = '"' + path + '"'; - } - else { - path = "'" + path + "'"; - } - var startPosition = line.indexOf(path); - var endPosition = startPosition + path.length; - var atomTokens = []; - atomTokens.push(this.registry.createToken(line.substr(0, startPosition), ['source.ts', 'keyword'])); - atomTokens.push(this.registry.createToken(line.substr(startPosition, path.length), ['source.ts', argumentType])); - atomTokens.push(this.registry.createToken(line.substr(endPosition, line.length - endPosition), ['source.ts', 'keyword'])); - return { tokens: atomTokens, ruleStack: [] }; - } - else { - return this.convertTsTokensToAtomTokens(tsTokensWithRuleStack); - } - }; - TypeScriptSemanticGrammar.prototype.getFullTripleSlashReferencePathTokensForLine = function (line) { - var tsTokensWithRuleStack = this.getTsTokensForLine(line); - var matches = line.match(this.fullTripleSlashReferencePathRegEx); - return this.getFullTripleSlashTokensForLine(line, matches, 'reference.path.string'); - }; - TypeScriptSemanticGrammar.prototype.getFullTripleSlashAMDModuleNameTokensForLine = function (line) { - var tsTokensWithRuleStack = this.getTsTokensForLine(line); - var matches = line.match(this.fullTripleSlashAMDNameRegEx); - return this.getFullTripleSlashTokensForLine(line, matches, 'module.name.string'); - }; - TypeScriptSemanticGrammar.prototype.getFullTripleSlashAMDDependencyPathTokensForLine = function (line) { - var tsTokensWithRuleStack = this.getTsTokensForLine(line); - var matches = line.match(this.fullTripleSlashAMDDependencyPathRegEx); - return this.getFullTripleSlashTokensForLine(line, matches, 'dependency.path.string'); - }; - TypeScriptSemanticGrammar.prototype.getImportRequireTokensForLine = function (line) { - var tsTokensWithRuleStack = this.getTsTokensForLine(line); - tsTokensWithRuleStack.tokens.forEach(function (t) { - if (t.style[0] == "identifier") { - t.style = ["require.identifier"]; - } - if (t.style[0] == "string") { - t.style = ["require.path.string"]; - } - }); - return this.convertTsTokensToAtomTokens(tsTokensWithRuleStack); - }; - TypeScriptSemanticGrammar.prototype.getEs6importTokensForLine = function (line) { - var tsTokensWithRuleStack = this.getTsTokensForLine(line); - tsTokensWithRuleStack.tokens.forEach(function (t) { - if (t.style[0] == "identifier") { - t.style = ["es6import.identifier"]; - } - if (t.style[0] == "string") { - t.style = ["es6import.path.string"]; - } - }); - return this.convertTsTokensToAtomTokens(tsTokensWithRuleStack); - }; - TypeScriptSemanticGrammar.prototype.getTsTokensForLine = function (line, finalLexState) { - var _this = this; - if (finalLexState === void 0) { finalLexState = ts.EndOfLineState.None; } - var output = this.classifier.getClassificationsForLine(line, finalLexState, true); - var ruleStack = [output.finalLexState]; - var classificationResults = output.entries; - if (!classificationResults.length) - return { tokens: [{ style: ['whitespace'], str: '' }], ruleStack: ruleStack }; - var totalLength = this.trailingWhiteSpaceLength; - var tokens = utils.selectMany(classificationResults.map(function (info) { - var tokenStartPosition = totalLength; - var str = line.substr(tokenStartPosition, info.length); - totalLength = totalLength + info.length; - var style = getAtomStyleForToken(info, str); - if (style == 'comment.block') { - var toret = []; - var match = void 0; - while (match = _this.todoRegex.exec(str)) { - var start = match.index; - var length = match[1].length; - var before = str.substr(0, start); - var actual = match[1]; - toret.push({ style: ['comment.block'], str: before }); - toret.push({ style: ['comment.block', 'storage.type.class'], str: actual }); - str = str.substr(start + length); - } - toret.push({ style: ['comment.block'], str: str }); - return toret; - } - return [{ style: [style], str: str }]; - })); - return { tokens: tokens, ruleStack: ruleStack }; - }; - TypeScriptSemanticGrammar.prototype.getAtomTokensForLine = function (line, finalLexState) { - var tsTokensWithRuleStack = this.getTsTokensForLine(line, finalLexState); - return this.convertTsTokensToAtomTokens(tsTokensWithRuleStack); - }; - TypeScriptSemanticGrammar.prototype.convertTsTokensToAtomTokens = function (tsTokensWithRuleStack) { - var _this = this; - var tokens = tsTokensWithRuleStack.tokens.map(function (info) { - var atomToken = _this.registry.createToken(info.str, ["source.ts"].concat(info.style)); - return atomToken; - }); - return { tokens: tokens, ruleStack: tsTokensWithRuleStack.ruleStack }; - }; - return TypeScriptSemanticGrammar; -}(AtomTSBaseGrammar)); -exports.TypeScriptSemanticGrammar = TypeScriptSemanticGrammar; -function getAtomStyleForToken(token, str) { - switch (token.classification) { - case TokenClass.Punctuation: - switch (str) { - case '{': - return "punctuation.section.scope.begin.ts"; - case '}': - return "punctuation.section.scope.end.ts"; - case ')': - return "meta.brace.round.ts"; - case '(': - return "meta.brace.round.ts"; - case ';': - return "punctuation.terminator.statement.ts"; - default: - return "punctuation"; - } - case TokenClass.Keyword: - switch (str) { - case 'static': - case 'public': - case 'private': - case 'protected': - case 'export': - case 'get': - case 'set': - return 'support.function'; - case 'class': - case 'module': - case 'var': - return 'storage.modifier'; - case 'function': - return 'storage.type.function'; - case 'string': - case 'number': - case 'void': - case 'boolean': - return 'keyword'; - default: - return 'keyword'; - } - case TokenClass.Operator: - return 'keyword.operator.js'; - case TokenClass.Comment: - return 'comment.block'; - case TokenClass.Whitespace: - return 'whitespace'; - case TokenClass.Identifier: - return 'identifier'; - case TokenClass.NumberLiteral: - return 'constant.numeric'; - case TokenClass.StringLiteral: - return 'string'; - case TokenClass.RegExpLiteral: - return 'constant.character'; - default: - return null; - } -} diff --git a/dist/main/atom/atomUtils.js b/dist/main/atom/utils/atom.js similarity index 68% rename from dist/main/atom/atomUtils.js rename to dist/main/atom/utils/atom.js index 7c9eb3896..780b2448a 100644 --- a/dist/main/atom/atomUtils.js +++ b/dist/main/atom/utils/atom.js @@ -1,19 +1,26 @@ "use strict"; -var path = require("path"); -var fs = require("fs"); -var fsu = require("../utils/fsUtil"); -var _atom = require("atom"); -var url = require("url"); +Object.defineProperty(exports, "__esModule", { value: true }); +const Atom = require("atom"); +const fs = require("fs"); +const path = require("path"); +const url = require("url"); +const _1 = require("./"); +// Return line/offset position in the editor using 1-indexed coordinates function getEditorPosition(editor) { - var bufferPos = editor.getCursorBufferPosition(); - return getEditorPositionForBufferPosition(editor, bufferPos); + const pos = editor.getCursorBufferPosition(); + return { + line: pos.row + 1, + offset: pos.column + 1 + }; } exports.getEditorPosition = getEditorPosition; -function getEditorPositionForBufferPosition(editor, bufferPos) { - var buffer = editor.getBuffer(); - return buffer.characterIndexForPosition(bufferPos); +function isTypescriptFile(filePath) { + if (!filePath) + return false; + const ext = path.extname(filePath); + return ext === ".ts" || ext === ".tsx"; } -exports.getEditorPositionForBufferPosition = getEditorPositionForBufferPosition; +exports.isTypescriptFile = isTypescriptFile; function isAllowedExtension(ext) { return (ext == '.ts' || ext == '.tst' || ext == '.tsx'); } @@ -39,6 +46,7 @@ function onDiskAndTs(editor) { return false; } exports.onDiskAndTs = onDiskAndTs; +/** Either ts or tsconfig */ function onDiskAndTsRelated(editor) { if (editor instanceof require('atom').TextEditor) { var filePath = editor.getPath(); @@ -59,71 +67,70 @@ function onDiskAndTsRelated(editor) { } exports.onDiskAndTsRelated = onDiskAndTsRelated; function getFilePathPosition() { - var editor = atom.workspace.getActiveTextEditor(); - var filePath = editor.getPath(); - var position = getEditorPosition(editor); - return { filePath: filePath, position: position }; + const editor = atom.workspace.getActiveTextEditor(); + return Object.assign({ file: editor.getPath() }, getEditorPosition(editor)); } exports.getFilePathPosition = getFilePathPosition; function getFilePath() { var editor = atom.workspace.getActiveTextEditor(); var filePath = editor.getPath(); - return { filePath: filePath }; + return { filePath }; } exports.getFilePath = getFilePath; function getEditorsForAllPaths(filePaths) { var map = {}; - var activeEditors = atom.workspace.getTextEditors().filter(function (editor) { return !!editor.getPath(); }); + var activeEditors = atom.workspace.getTextEditors().filter(editor => !!editor.getPath()); function addConsistentlyToMap(editor) { - map[fsu.consistentPath(editor.getPath())] = editor; + map[_1.consistentPath(editor.getPath())] = editor; } activeEditors.forEach(addConsistentlyToMap); - var newPaths = filePaths.filter(function (p) { return !map[p]; }); + /// find the editors that are not in here + var newPaths = filePaths.filter(p => !map[p]); if (!newPaths.length) return Promise.resolve(map); - var promises = newPaths.map(function (p) { return atom.workspace.open(p, {}); }); - return Promise.all(promises).then(function (editors) { - editors.forEach(addConsistentlyToMap); + var promises = newPaths.map(p => atom.workspace.open(p, {})); // Update Atom typings! + return Promise.all(promises).then(editors => { + editors.forEach(editor => addConsistentlyToMap(editor)); return map; }); } exports.getEditorsForAllPaths = getEditorsForAllPaths; function getRangeForTextSpan(editor, ts) { - var buffer = editor.buffer; var start = editor.buffer.positionForCharacterIndex(ts.start); var end = editor.buffer.positionForCharacterIndex(ts.start + ts.length); - var range = new _atom.Range(start, end); + var range = new Atom.Range(start, end); return range; } exports.getRangeForTextSpan = getRangeForTextSpan; +/** only the editors that are persisted to disk. And are of type TypeScript */ function getTypeScriptEditorsWithPaths() { return atom.workspace.getTextEditors() - .filter(function (editor) { return !!editor.getPath(); }) - .filter(function (editor) { return (path.extname(editor.getPath()) === '.ts'); }); + .filter(editor => !!editor.getPath()) + .filter(editor => (path.extname(editor.getPath()) === '.ts')); } exports.getTypeScriptEditorsWithPaths = getTypeScriptEditorsWithPaths; function getOpenTypeScritEditorsConsistentPaths() { - return getTypeScriptEditorsWithPaths().map(function (e) { return fsu.consistentPath(e.getPath()); }); + return getTypeScriptEditorsWithPaths().map(e => _1.consistentPath(e.getPath())); } exports.getOpenTypeScritEditorsConsistentPaths = getOpenTypeScritEditorsConsistentPaths; function quickNotifySuccess(htmlMessage) { var notification = atom.notifications.addSuccess(htmlMessage, { dismissable: true }); - setTimeout(function () { + setTimeout(() => { notification.dismiss(); }, 800); } exports.quickNotifySuccess = quickNotifySuccess; function quickNotifyWarning(htmlMessage) { var notification = atom.notifications.addWarning(htmlMessage, { dismissable: true }); - setTimeout(function () { + setTimeout(() => { notification.dismiss(); }, 800); } exports.quickNotifyWarning = quickNotifyWarning; function formatCode(editor, edits) { - for (var i = edits.length - 1; i >= 0; i--) { - var edit = edits[i]; - editor.setTextInBufferRange([[edit.start.line, edit.start.col], [edit.end.line, edit.end.col]], edit.newText); + // The code edits need to be applied in reverse order + for (let i = edits.length - 1; i >= 0; i--) { + editor.setTextInBufferRange(_1.spanToRange(edits[i]), edits[i].newText); } } exports.formatCode = formatCode; @@ -140,8 +147,14 @@ function kindToColor(kind) { } } exports.kindToColor = kindToColor; +/** See types : + * https://github.com/atom-community/autocomplete-plus/pull/334#issuecomment-85697409 + */ function kindToType(kind) { + // variable, constant, property, value, method, function, class, type, keyword, tag, snippet, import, require switch (kind) { + case 'const': + return 'constant'; case 'interface': return 'type'; case 'identifier': @@ -150,6 +163,7 @@ function kindToType(kind) { return 'function'; case 'local var': return 'variable'; + case 'let': case 'var': case 'parameter': return 'variable'; @@ -162,6 +176,7 @@ function kindToType(kind) { } } exports.kindToType = kindToType; +/** Utility functions for commands */ function commandForTypeScript(e) { var editor = atom.workspace.getActiveTextEditor(); if (!editor) @@ -172,9 +187,10 @@ function commandForTypeScript(e) { return true; } exports.commandForTypeScript = commandForTypeScript; +/** Gets the consisten path for the current editor */ function getCurrentPath() { var editor = atom.workspace.getActiveTextEditor(); - return fsu.consistentPath(editor.getPath()); + return _1.consistentPath(editor.getPath()); } exports.getCurrentPath = getCurrentPath; exports.knownScopes = { @@ -186,34 +202,41 @@ function editorInTheseScopes(matches) { var editor = atom.workspace.getActiveTextEditor(); var scopes = editor.getLastCursor().getScopeDescriptor().scopes; var lastScope = scopes[scopes.length - 1]; - if (matches.some(function (p) { return lastScope === p; })) + if (matches.some(p => lastScope === p)) return lastScope; else return ''; } exports.editorInTheseScopes = editorInTheseScopes; +/** One less level of indirection */ function getActiveEditor() { return atom.workspace.getActiveTextEditor(); } exports.getActiveEditor = getActiveEditor; +/** + * Uri for filepath based on protocol + */ function uriForPath(uriProtocol, filePath) { return uriProtocol + "//" + filePath; } exports.uriForPath = uriForPath; +/** + * Registers an opener with atom + */ function registerOpener(config) { - atom.commands.add(config.commandSelector, config.commandName, function (e) { + atom.commands.add(config.commandSelector, config.commandName, (e) => { if (!commandForTypeScript(e)) return; var uri = uriForPath(config.uriProtocol, getCurrentPath()); var old_pane = atom.workspace.paneForURI(uri); if (old_pane) { - old_pane.destroyItem(old_pane.itemForUri(uri)); + old_pane.destroyItem(old_pane.itemForURI(uri)); } atom.workspace.open(uri, config.getData()); }); atom.workspace.addOpener(function (uri, data) { try { - var protocol = url.parse(uri).protocol; + var { protocol } = url.parse(uri); } catch (error) { return; @@ -226,16 +249,24 @@ function registerOpener(config) { } exports.registerOpener = registerOpener; function triggerLinter() { + // also invalidate linter atom.commands.dispatch(atom.views.getView(atom.workspace.getActiveTextEditor()), 'linter:lint'); } exports.triggerLinter = triggerLinter; +/** + * converts "c:\dev\somethin\bar.ts" to "~something\bar". + */ function getFilePathRelativeToAtomProject(filePath) { - filePath = fsu.consistentPath(filePath); + filePath = _1.consistentPath(filePath); + // Sample: + // atom.project.relativize(`D:/REPOS/atom-typescript/lib/main/atom/atomUtils.ts`) return '~' + atom.project.relativize(filePath); } exports.getFilePathRelativeToAtomProject = getFilePathRelativeToAtomProject; -function openFile(filePath, position) { - if (position === void 0) { position = {}; } +/** + * Opens the given file in the same project + */ +function openFile(filePath, position = {}) { var config = {}; if (position.line) { config.initialLine = position.line - 1; @@ -246,17 +277,4 @@ function openFile(filePath, position) { atom.workspace.open(filePath, config); } exports.openFile = openFile; -var _snippetsManager; -function _setSnippetsManager(snippetsManager) { - _snippetsManager = snippetsManager; -} -exports._setSnippetsManager = _setSnippetsManager; -function insertSnippet(snippet, editor, cursor) { - if (_snippetsManager) { - _snippetsManager.insertSnippet(snippet, editor, cursor); - } - else { - console.error('Why no snippet manager?'); - } -} -exports.insertSnippet = insertSnippet; +//# sourceMappingURL=atom.js.map \ No newline at end of file diff --git a/dist/main/atom/utils/atom.js.map b/dist/main/atom/utils/atom.js.map new file mode 100644 index 000000000..a4154caa6 --- /dev/null +++ b/dist/main/atom/utils/atom.js.map @@ -0,0 +1 @@ +{"version":3,"file":"atom.js","sourceRoot":"","sources":["../../../../lib/main/atom/utils/atom.ts"],"names":[],"mappings":";;AAAA,6BAA4B;AAC5B,yBAAwB;AACxB,6BAA4B;AAC5B,2BAA0B;AAC1B,yBAMW;AAEX,wEAAwE;AACxE,2BAAkC,MAAwB;IACtD,MAAM,GAAG,GAAG,MAAM,CAAC,uBAAuB,EAAE,CAAA;IAC5C,MAAM,CAAC;QACL,IAAI,EAAE,GAAG,CAAC,GAAG,GAAG,CAAC;QACjB,MAAM,EAAE,GAAG,CAAC,MAAM,GAAG,CAAC;KACvB,CAAA;AACL,CAAC;AAND,8CAMC;AAED,0BAAiC,QAAiB;IAChD,EAAE,CAAC,CAAC,CAAC,QAAQ,CAAC;QAAC,MAAM,CAAC,KAAK,CAAA;IAE3B,MAAM,GAAG,GAAG,IAAI,CAAC,OAAO,CAAC,QAAQ,CAAC,CAAA;IAClC,MAAM,CAAC,GAAG,KAAK,KAAK,IAAI,GAAG,KAAK,MAAM,CAAA;AACxC,CAAC;AALD,4CAKC;AAED,4BAAmC,GAAW;IAC1C,MAAM,CAAC,CAAC,GAAG,IAAI,KAAK,IAAI,GAAG,IAAI,MAAM,IAAI,GAAG,IAAI,MAAM,CAAC,CAAC;AAC5D,CAAC;AAFD,gDAEC;AAED;IACI,IAAI,MAAM,GAAG,IAAI,CAAC,SAAS,CAAC,mBAAmB,EAAE,CAAC;IAClD,MAAM,CAAC,WAAW,CAAC,MAAM,CAAC,CAAC;AAC/B,CAAC;AAHD,8DAGC;AAED,qBAA4B,MAAwB;IAChD,EAAE,CAAC,CAAC,MAAM,YAAY,OAAO,CAAC,MAAM,CAAC,CAAC,UAAU,CAAC,CAAC,CAAC;QAC/C,IAAI,QAAQ,GAAG,MAAM,CAAC,OAAO,EAAE,CAAC;QAChC,EAAE,CAAC,CAAC,CAAC,QAAQ,CAAC,CAAC,CAAC;YACZ,MAAM,CAAC,KAAK,CAAC;QACjB,CAAC;QACD,IAAI,GAAG,GAAG,IAAI,CAAC,OAAO,CAAC,QAAQ,CAAC,CAAC;QACjC,EAAE,CAAC,CAAC,kBAAkB,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC;YAC1B,EAAE,CAAC,CAAC,EAAE,CAAC,UAAU,CAAC,QAAQ,CAAC,CAAC,CAAC,CAAC;gBAC1B,MAAM,CAAC,IAAI,CAAC;YAChB,CAAC;QACL,CAAC;IACL,CAAC;IACD,MAAM,CAAC,KAAK,CAAC;AACjB,CAAC;AAdD,kCAcC;AAED,4BAA4B;AAC5B,4BAAmC,MAAwB;IACvD,EAAE,CAAC,CAAC,MAAM,YAAY,OAAO,CAAC,MAAM,CAAC,CAAC,UAAU,CAAC,CAAC,CAAC;QAC/C,IAAI,QAAQ,GAAG,MAAM,CAAC,OAAO,EAAE,CAAC;QAChC,EAAE,CAAC,CAAC,CAAC,QAAQ,CAAC,CAAC,CAAC;YACZ,MAAM,CAAC,KAAK,CAAC;QACjB,CAAC;QACD,IAAI,GAAG,GAAG,IAAI,CAAC,OAAO,CAAC,QAAQ,CAAC,CAAC;QACjC,EAAE,CAAC,CAAC,kBAAkB,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC;YAC1B,EAAE,CAAC,CAAC,EAAE,CAAC,UAAU,CAAC,QAAQ,CAAC,CAAC,CAAC,CAAC;gBAC1B,MAAM,CAAC,IAAI,CAAC;YAChB,CAAC;QACL,CAAC;QACD,EAAE,CAAC,CAAC,QAAQ,CAAC,QAAQ,CAAC,eAAe,CAAC,CAAC,CAAC,CAAC;YACrC,MAAM,CAAC,IAAI,CAAC;QAChB,CAAC;IACL,CAAC;IACD,MAAM,CAAC,KAAK,CAAC;AACjB,CAAC;AAjBD,gDAiBC;AAED;IACI,MAAM,MAAM,GAAG,IAAI,CAAC,SAAS,CAAC,mBAAmB,EAAE,CAAA;IACnD,MAAM,iBACJ,IAAI,EAAE,MAAM,CAAC,OAAO,EAAE,IACnB,iBAAiB,CAAC,MAAM,CAAC,EAC7B;AACL,CAAC;AAND,kDAMC;AAED;IACI,IAAI,MAAM,GAAG,IAAI,CAAC,SAAS,CAAC,mBAAmB,EAAE,CAAC;IAClD,IAAI,QAAQ,GAAG,MAAM,CAAC,OAAO,EAAE,CAAC;IAChC,MAAM,CAAC,EAAE,QAAQ,EAAE,CAAC;AACxB,CAAC;AAJD,kCAIC;AAED,+BAAsC,SAAmB;IACrD,IAAI,GAAG,GAAQ,EAAE,CAAC;IAClB,IAAI,aAAa,GAAG,IAAI,CAAC,SAAS,CAAC,cAAc,EAAE,CAAC,MAAM,CAAC,MAAM,IAAG,CAAC,CAAC,MAAM,CAAC,OAAO,EAAE,CAAC,CAAC;IAExF,8BAA8B,MAAwB;QAClD,GAAG,CAAC,iBAAc,CAAC,MAAM,CAAC,OAAO,EAAE,CAAC,CAAC,GAAG,MAAM,CAAC;IACnD,CAAC;IAED,aAAa,CAAC,OAAO,CAAC,oBAAoB,CAAC,CAAC;IAE5C,yCAAyC;IACzC,IAAI,QAAQ,GAAG,SAAS,CAAC,MAAM,CAAC,CAAC,IAAG,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,CAAC;IAC7C,EAAE,CAAC,CAAC,CAAC,QAAQ,CAAC,MAAM,CAAC;QAAC,MAAM,CAAC,OAAO,CAAC,OAAO,CAAC,GAAG,CAAC,CAAC;IAElD,IAAI,QAAQ,GAAG,QAAQ,CAAC,GAAG,CAAC,CAAC,IAAG,IAAI,CAAC,SAAS,CAAC,IAAI,CAAC,CAAC,EAAE,EAAE,CAAQ,CAAC,CAAC,CAAC,uBAAuB;IAE3F,MAAM,CAAC,OAAO,CAAC,GAAG,CAAC,QAAQ,CAAC,CAAC,IAAI,CAAC,OAAO;QACrC,OAAO,CAAC,OAAO,CAAC,MAAM,IAAI,oBAAoB,CAAC,MAAM,CAAC,CAAC,CAAC;QAExD,MAAM,CAAC,GAAG,CAAC;IACf,CAAC,CAAC,CAAC;AACP,CAAC;AArBD,sDAqBC;AAED,6BAAoC,MAAwB,EAAE,EAAqC;IAC/F,IAAI,KAAK,GAAG,MAAM,CAAC,MAAM,CAAC,yBAAyB,CAAC,EAAE,CAAC,KAAK,CAAC,CAAC;IAC9D,IAAI,GAAG,GAAG,MAAM,CAAC,MAAM,CAAC,yBAAyB,CAAC,EAAE,CAAC,KAAK,GAAG,EAAE,CAAC,MAAM,CAAC,CAAC;IACxE,IAAI,KAAK,GAAG,IAAI,IAAI,CAAC,KAAK,CAAC,KAAK,EAAE,GAAG,CAAC,CAAC;IACvC,MAAM,CAAC,KAAK,CAAC;AACjB,CAAC;AALD,kDAKC;AAED,8EAA8E;AAC9E;IACI,MAAM,CAAC,IAAI,CAAC,SAAS,CAAC,cAAc,EAAE;SACjC,MAAM,CAAC,MAAM,IAAG,CAAC,CAAC,MAAM,CAAC,OAAO,EAAE,CAAC;SACnC,MAAM,CAAC,MAAM,IAAG,CAAC,IAAI,CAAC,OAAO,CAAC,MAAM,CAAC,OAAO,EAAE,CAAC,KAAK,KAAK,CAAC,CAAC,CAAC;AACrE,CAAC;AAJD,sEAIC;AAED;IACI,MAAM,CAAC,6BAA6B,EAAE,CAAC,GAAG,CAAC,CAAC,IAAG,iBAAc,CAAC,CAAC,CAAC,OAAO,EAAE,CAAC,CAAC,CAAC;AAChF,CAAC;AAFD,wFAEC;AAED,4BAAmC,WAAmB;IAClD,IAAI,YAAY,GAAG,IAAI,CAAC,aAAa,CAAC,UAAU,CAAC,WAAW,EAAE,EAAE,WAAW,EAAE,IAAI,EAAE,CAAC,CAAC;IACrF,UAAU,CAAC;QACP,YAAY,CAAC,OAAO,EAAE,CAAA;IAC1B,CAAC,EAAE,GAAG,CAAC,CAAC;AACZ,CAAC;AALD,gDAKC;AAED,4BAAmC,WAAmB;IAClD,IAAI,YAAY,GAAG,IAAI,CAAC,aAAa,CAAC,UAAU,CAAC,WAAW,EAAE,EAAE,WAAW,EAAE,IAAI,EAAE,CAAC,CAAC;IACrF,UAAU,CAAC;QACP,YAAY,CAAC,OAAO,EAAE,CAAA;IAC1B,CAAC,EAAE,GAAG,CAAC,CAAC;AACZ,CAAC;AALD,gDAKC;AAED,oBAA2B,MAAwB,EAAE,KAAiB;IACpE,qDAAqD;IACrD,GAAG,CAAC,CAAC,IAAI,CAAC,GAAG,KAAK,CAAC,MAAM,GAAG,CAAC,EAAE,CAAC,IAAI,CAAC,EAAE,CAAC,EAAE,EAAE,CAAC;QAC3C,MAAM,CAAC,oBAAoB,CAAC,cAAW,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,EAAE,KAAK,CAAC,CAAC,CAAC,CAAC,OAAO,CAAC,CAAA;IACtE,CAAC;AACH,CAAC;AALD,gCAKC;AAED,qBAA4B,IAAY;IACpC,MAAM,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC;QACX,KAAK,WAAW;YACZ,MAAM,CAAC,iBAAiB,CAAC;QAC7B,KAAK,SAAS;YACV,MAAM,CAAC,kBAAkB,CAAC;QAC9B,KAAK,OAAO;YACR,MAAM,CAAC,kBAAkB,CAAC;QAC9B;YACI,MAAM,CAAC,OAAO,CAAC;IACvB,CAAC;AACL,CAAC;AAXD,kCAWC;AAED;;GAEG;AACH,oBAA2B,IAAY;IACrC,6GAA6G;IAC3G,MAAM,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC;QACX,KAAK,OAAO;YACR,MAAM,CAAC,UAAU,CAAC;QACtB,KAAK,WAAW;YACZ,MAAM,CAAC,MAAM,CAAC;QAClB,KAAK,YAAY;YACb,MAAM,CAAC,UAAU,CAAC;QACtB,KAAK,gBAAgB;YACjB,MAAM,CAAC,UAAU,CAAC;QACtB,KAAK,WAAW;YACZ,MAAM,CAAC,UAAU,CAAC;QACtB,KAAK,KAAK,CAAC;QACX,KAAK,KAAK,CAAC;QACX,KAAK,WAAW;YACZ,MAAM,CAAC,UAAU,CAAC;QACtB,KAAK,OAAO;YACR,MAAM,CAAC,QAAQ,CAAC;QACpB,KAAK,gBAAgB;YACjB,MAAM,CAAC,MAAM,CAAC;QAClB;YACI,MAAM,CAAC,IAAI,CAAC,KAAK,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,CAAC;IAClC,CAAC;AACL,CAAC;AAxBD,gCAwBC;AAED,qCAAqC;AACrC,8BAAqC,CAAwB;IACzD,IAAI,MAAM,GAAG,IAAI,CAAC,SAAS,CAAC,mBAAmB,EAAE,CAAC;IAClD,EAAE,CAAC,CAAC,CAAC,MAAM,CAAC;QAAC,MAAM,CAAC,CAAC,CAAC,eAAe,EAAE,IAAI,KAAK,CAAC;IACjD,IAAI,GAAG,GAAG,IAAI,CAAC,OAAO,CAAC,MAAM,CAAC,OAAO,EAAE,CAAC,CAAC;IACzC,EAAE,CAAC,CAAC,CAAC,kBAAkB,CAAC,GAAG,CAAC,CAAC;QAAC,MAAM,CAAC,CAAC,CAAC,eAAe,EAAE,IAAI,KAAK,CAAC;IAElE,MAAM,CAAC,IAAI,CAAC;AAChB,CAAC;AAPD,oDAOC;AAED,qDAAqD;AACrD;IACI,IAAI,MAAM,GAAG,IAAI,CAAC,SAAS,CAAC,mBAAmB,EAAE,CAAC;IAClD,MAAM,CAAC,iBAAc,CAAC,MAAM,CAAC,OAAO,EAAE,CAAC,CAAC;AAC5C,CAAC;AAHD,wCAGC;AAEU,QAAA,WAAW,GAAG;IACrB,SAAS,EAAE,uBAAuB;IAClC,OAAO,EAAE,qBAAqB;IAC9B,SAAS,EAAE,uBAAuB;CACrC,CAAA;AAED,6BAAoC,OAAiB;IACjD,IAAI,MAAM,GAAG,IAAI,CAAC,SAAS,CAAC,mBAAmB,EAAE,CAAC;IAClD,IAAI,MAAM,GAAG,MAAM,CAAC,aAAa,EAAE,CAAC,kBAAkB,EAAE,CAAC,MAAM,CAAC;IAChE,IAAI,SAAS,GAAG,MAAM,CAAC,MAAM,CAAC,MAAM,GAAG,CAAC,CAAC,CAAC;IAC1C,EAAE,CAAC,CAAC,OAAO,CAAC,IAAI,CAAC,CAAC,IAAG,SAAS,KAAK,CAAC,CAAC,CAAC;QAClC,MAAM,CAAC,SAAS,CAAC;IACrB,IAAI;QACA,MAAM,CAAC,EAAE,CAAC;AAClB,CAAC;AARD,kDAQC;AAED,oCAAoC;AACpC;IACI,MAAM,CAAC,IAAI,CAAC,SAAS,CAAC,mBAAmB,EAAE,CAAC;AAChD,CAAC;AAFD,0CAEC;AAWD;;GAEG;AACH,oBAA2B,WAAmB,EAAE,QAAgB;IAC5D,MAAM,CAAC,WAAW,GAAG,IAAI,GAAG,QAAQ,CAAC;AACzC,CAAC;AAFD,gCAEC;AAED;;GAEG;AACH,wBAAkC,MAAuB;IACrD,IAAI,CAAC,QAAQ,CAAC,GAAG,CAAC,MAAM,CAAC,eAAe,EAAE,MAAM,CAAC,WAAW,EAAE,CAAC,CAAC;QAC5D,EAAE,CAAC,CAAC,CAAC,oBAAoB,CAAC,CAAC,CAAC,CAAC;YAAC,MAAM,CAAC;QAErC,IAAI,GAAG,GAAG,UAAU,CAAC,MAAM,CAAC,WAAW,EAAE,cAAc,EAAE,CAAC,CAAC;QAC3D,IAAI,QAAQ,GAAG,IAAI,CAAC,SAAS,CAAC,UAAU,CAAC,GAAG,CAAC,CAAC;QAC9C,EAAE,CAAC,CAAC,QAAQ,CAAC,CAAC,CAAC;YACX,QAAQ,CAAC,WAAW,CAAC,QAAQ,CAAC,UAAU,CAAC,GAAG,CAAC,CAAC,CAAC;QACnD,CAAC;QAED,IAAI,CAAC,SAAS,CAAC,IAAI,CAAC,GAAG,EAAE,MAAM,CAAC,OAAO,EAAE,CAAC,CAAC;IAC/C,CAAC,CAAC,CAAC;IAEH,IAAI,CAAC,SAAS,CAAC,SAAS,CAAC,UAAS,GAAW,EAAE,IAAO;QAClD,IAAI,CAAC;YACD,IAAI,EAAC,QAAQ,EAAC,GAAG,GAAG,CAAC,KAAK,CAAC,GAAG,CAAC,CAAC;QACpC,CAAC;QACD,KAAK,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC;YACX,MAAM,CAAC;QACX,CAAC;QAED,EAAE,CAAC,CAAC,QAAQ,KAAK,MAAM,CAAC,WAAW,CAAC,CAAC,CAAC;YAClC,MAAM,CAAC;QACX,CAAC;QAED,MAAM,CAAC,MAAM,CAAC,MAAM,CAAC,IAAI,CAAC,CAAC;IAC/B,CAAC,CAAC,CAAC;AACP,CAAC;AA3BD,wCA2BC;AAED;IACI,yBAAyB;IACzB,IAAI,CAAC,QAAQ,CAAC,QAAQ,CAClB,IAAI,CAAC,KAAK,CAAC,OAAO,CAAC,IAAI,CAAC,SAAS,CAAC,mBAAmB,EAAE,CAAC,EACxD,aAAa,CAAC,CAAC;AACvB,CAAC;AALD,sCAKC;AAED;;GAEG;AACH,0CAAiD,QAAgB;IAC7D,QAAQ,GAAG,iBAAc,CAAC,QAAQ,CAAC,CAAC;IACpC,UAAU;IACV,iFAAiF;IACjF,MAAM,CAAC,GAAG,GAAG,IAAI,CAAC,OAAO,CAAC,UAAU,CAAC,QAAQ,CAAC,CAAC;AACnD,CAAC;AALD,4EAKC;AAED;;GAEG;AACH,kBAAyB,QAAgB,EAAE,WAA4C,EAAE;IACrF,IAAI,MAAM,GAAQ,EAAE,CAAC;IACrB,EAAE,CAAC,CAAC,QAAQ,CAAC,IAAI,CAAC,CAAC,CAAC;QAChB,MAAM,CAAC,WAAW,GAAG,QAAQ,CAAC,IAAI,GAAG,CAAC,CAAC;IAC3C,CAAC;IACD,EAAE,CAAC,CAAC,QAAQ,CAAC,GAAG,CAAC,CAAC,CAAC;QACf,MAAM,CAAC,aAAa,GAAG,QAAQ,CAAC,GAAG,CAAC;IACxC,CAAC;IACD,IAAI,CAAC,SAAS,CAAC,IAAI,CAAC,QAAQ,EAAE,MAAM,CAAC,CAAC;AAC1C,CAAC;AATD,4BASC"} \ No newline at end of file diff --git a/dist/main/atom/utils/fs.js b/dist/main/atom/utils/fs.js new file mode 100644 index 000000000..363403906 --- /dev/null +++ b/dist/main/atom/utils/fs.js @@ -0,0 +1,37 @@ +/** + * Wraps fs and path into a nice "consistentPath" API + */ +"use strict"; +Object.defineProperty(exports, "__esModule", { value: true }); +function consistentPath(filePath) { + return filePath.split('\\').join('/'); +} +exports.consistentPath = consistentPath; +const path = require("path"); +// Atom uses system dependent path separators while Typescript uses /. Unfortunately, we +// needs this to make sure things like lint errors work. +exports.systemPath = path.sep === "\\" ? filePath => filePath.replace(/\//g, "\\") : filePath => filePath; +/** + * Resolves to to an absolute path. + * @param from,to,to,to... + */ +function resolve(...args) { + return consistentPath(path.resolve(...args)); +} +exports.resolve = resolve; +/** + * Converts "C:\boo" , "C:\boo\foo.ts" => "./foo.ts"; Works on unix as well. + */ +function makeRelativePath(relativeFolder, filePath) { + var relativePath = path.relative(relativeFolder, filePath).split('\\').join('/'); + if (relativePath[0] !== '.') { + relativePath = './' + relativePath; + } + return relativePath; +} +exports.makeRelativePath = makeRelativePath; +function removeExt(filePath) { + return filePath.substr(0, filePath.lastIndexOf('.')); +} +exports.removeExt = removeExt; +//# sourceMappingURL=fs.js.map \ No newline at end of file diff --git a/dist/main/atom/utils/fs.js.map b/dist/main/atom/utils/fs.js.map new file mode 100644 index 000000000..e7ed3aaa7 --- /dev/null +++ b/dist/main/atom/utils/fs.js.map @@ -0,0 +1 @@ +{"version":3,"file":"fs.js","sourceRoot":"","sources":["../../../../lib/main/atom/utils/fs.ts"],"names":[],"mappings":"AAAA;;GAEG;;;AAEH,wBAA+B,QAAgB;IAC7C,MAAM,CAAC,QAAQ,CAAC,KAAK,CAAC,IAAI,CAAC,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC;AACxC,CAAC;AAFD,wCAEC;AAED,6BAA6B;AAE7B,wFAAwF;AACxF,wDAAwD;AAC3C,QAAA,UAAU,GAAiC,IAAI,CAAC,GAAG,KAAK,IAAI,GAAG,QAAQ,IAAI,QAAQ,CAAC,OAAO,CAAC,KAAK,EAAE,IAAI,CAAC,GAAG,QAAQ,IAAI,QAAQ,CAAA;AAE5I;;;GAGG;AACH,iBAAwB,GAAG,IAAc;IACrC,MAAM,CAAC,cAAc,CAAC,IAAI,CAAC,OAAO,CAAC,GAAG,IAAI,CAAC,CAAC,CAAC;AACjD,CAAC;AAFD,0BAEC;AAED;;GAEG;AACH,0BAAiC,cAAsB,EAAE,QAAgB;IACrE,IAAI,YAAY,GAAG,IAAI,CAAC,QAAQ,CAAC,cAAc,EAAE,QAAQ,CAAC,CAAC,KAAK,CAAC,IAAI,CAAC,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC;IACjF,EAAE,CAAC,CAAC,YAAY,CAAC,CAAC,CAAC,KAAK,GAAG,CAAC,CAAC,CAAC;QAC1B,YAAY,GAAG,IAAI,GAAG,YAAY,CAAC;IACvC,CAAC;IACD,MAAM,CAAC,YAAY,CAAC;AACxB,CAAC;AAND,4CAMC;AAED,mBAA0B,QAAgB;IACtC,MAAM,CAAC,QAAQ,CAAC,MAAM,CAAC,CAAC,EAAE,QAAQ,CAAC,WAAW,CAAC,GAAG,CAAC,CAAC,CAAC;AACzD,CAAC;AAFD,8BAEC"} \ No newline at end of file diff --git a/dist/main/atom/utils/index.js b/dist/main/atom/utils/index.js new file mode 100644 index 000000000..43ae534bf --- /dev/null +++ b/dist/main/atom/utils/index.js @@ -0,0 +1,9 @@ +"use strict"; +function __export(m) { + for (var p in m) if (!exports.hasOwnProperty(p)) exports[p] = m[p]; +} +Object.defineProperty(exports, "__esModule", { value: true }); +__export(require("./atom")); +__export(require("./fs")); +__export(require("./ts")); +//# sourceMappingURL=index.js.map \ No newline at end of file diff --git a/dist/main/atom/utils/index.js.map b/dist/main/atom/utils/index.js.map new file mode 100644 index 000000000..1981a8b87 --- /dev/null +++ b/dist/main/atom/utils/index.js.map @@ -0,0 +1 @@ +{"version":3,"file":"index.js","sourceRoot":"","sources":["../../../../lib/main/atom/utils/index.ts"],"names":[],"mappings":";;;;;AAAA,4BAAsB;AACtB,0BAAoB;AACpB,0BAAoB"} \ No newline at end of file diff --git a/dist/main/atom/utils/ts.js b/dist/main/atom/utils/ts.js new file mode 100644 index 000000000..cae4be601 --- /dev/null +++ b/dist/main/atom/utils/ts.js @@ -0,0 +1,25 @@ +"use strict"; +Object.defineProperty(exports, "__esModule", { value: true }); +const atom_1 = require("atom"); +function locationToPoint(loc) { + return new atom_1.Point(loc.line - 1, loc.offset - 1); +} +exports.locationToPoint = locationToPoint; +function spanToRange(span) { + return locationsToRange(span.start, span.end); +} +exports.spanToRange = spanToRange; +function locationsToRange(start, end) { + return new atom_1.Range(locationToPoint(start), locationToPoint(end)); +} +exports.locationsToRange = locationsToRange; +function rangeToLocationRange(range) { + return { + line: range.start.row + 1, + offset: range.start.column + 1, + endLine: range.end.row + 1, + endOffset: range.end.column + 1 + }; +} +exports.rangeToLocationRange = rangeToLocationRange; +//# sourceMappingURL=ts.js.map \ No newline at end of file diff --git a/dist/main/atom/utils/ts.js.map b/dist/main/atom/utils/ts.js.map new file mode 100644 index 000000000..a3f03ee6b --- /dev/null +++ b/dist/main/atom/utils/ts.js.map @@ -0,0 +1 @@ +{"version":3,"file":"ts.js","sourceRoot":"","sources":["../../../../lib/main/atom/utils/ts.ts"],"names":[],"mappings":";;AACA,+BAAiC;AAkBjC,yBAAgC,GAAkB;IAChD,MAAM,CAAC,IAAI,YAAK,CAAC,GAAG,CAAC,IAAI,GAAC,CAAC,EAAE,GAAG,CAAC,MAAM,GAAC,CAAC,CAAC,CAAA;AAC5C,CAAC;AAFD,0CAEC;AAED,qBAA4B,IAAc;IACxC,MAAM,CAAC,gBAAgB,CAAC,IAAI,CAAC,KAAK,EAAE,IAAI,CAAC,GAAG,CAAC,CAAA;AAC/C,CAAC;AAFD,kCAEC;AAED,0BAAiC,KAAoB,EAAE,GAAkB;IACvE,MAAM,CAAC,IAAI,YAAK,CAAC,eAAe,CAAC,KAAK,CAAC,EAAE,eAAe,CAAC,GAAG,CAAC,CAAC,CAAA;AAChE,CAAC;AAFD,4CAEC;AAED,8BAAqC,KAAwB;IAC3D,MAAM,CAAC;QACL,IAAI,EAAE,KAAK,CAAC,KAAK,CAAC,GAAG,GAAG,CAAC;QACzB,MAAM,EAAE,KAAK,CAAC,KAAK,CAAC,MAAM,GAAG,CAAC;QAC9B,OAAO,EAAE,KAAK,CAAC,GAAG,CAAC,GAAG,GAAG,CAAC;QAC1B,SAAS,EAAE,KAAK,CAAC,GAAG,CAAC,MAAM,GAAG,CAAC;KAChC,CAAA;AACH,CAAC;AAPD,oDAOC"} \ No newline at end of file diff --git a/dist/main/atom/views/astView.js b/dist/main/atom/views/astView.js deleted file mode 100644 index 7ba81e9ce..000000000 --- a/dist/main/atom/views/astView.js +++ /dev/null @@ -1,158 +0,0 @@ -"use strict"; -var __extends = (this && this.__extends) || function (d, b) { - for (var p in b) if (b.hasOwnProperty(p)) d[p] = b[p]; - function __() { this.constructor = d; } - d.prototype = b === null ? Object.create(b) : (__.prototype = b.prototype, new __()); -}; -var sp = require("atom-space-pen-views"); -var atomUtils = require("../atomUtils"); -var parent = require("../../../worker/parent"); -var d3 = require("d3"); -exports.astURI = "ts-ast:"; -exports.astURIFull = "ts-ast-full:"; -var AstView = (function (_super) { - __extends(AstView, _super); - function AstView(filePath, text, full) { - var _this = _super.call(this) || this; - _this.filePath = filePath; - _this.text = text; - _this.full = full; - _this.getURI = function () { return atomUtils.uriForPath(_this.full ? exports.astURIFull : exports.astURI, _this.filePath); }; - _this.getTitle = function () { return 'TypeScript AST'; }; - _this.getIconName = function () { return 'repo-forked'; }; - _this.init(); - return _this; - } - AstView.content = function () { - var _this = this; - return this.div({ class: 'ast-view' }, function () { - _this.div({ style: 'display: flex' }, function () { - _this.div({ outlet: 'mainContent', style: 'width: 50%' }); - _this.pre({ class: 'raw-display', outlet: 'rawDisplay', style: 'width: 50%' }); - }); - }); - }; - AstView.prototype.init = function () { - var _this = this; - if (this.full) { - var query = parent.getASTFull({ filePath: this.filePath }); - } - else { - query = parent.getAST({ filePath: this.filePath }); - } - query.then(function (res) { - renderTree(res.root, _this.mainContent, function (node) { - var display = ("\n" + node.kind + "\n-------------------- AST --------------------\n" + node.rawJson + "\n-------------------- TEXT -------------------\n" + _this.text.substring(node.pos, node.end) + "\n ").trim(); - _this.rawDisplay.text(display); - }); - }); - }; - return AstView; -}(sp.ScrollView)); -exports.AstView = AstView; -function renderTree(rootNode, _mainContent, display) { - var root = { - dom: _mainContent[0], - jq: _mainContent - }; - var margin = { top: 30, right: 20, bottom: 30, left: 20 }; - var width = root.jq.width() - margin.left - margin.right; - var barHeight = 30; - var barWidth = width * .8; - var i = 0, duration = 400; - var tree = d3.layout.tree() - .nodeSize([0, 20]); - var diagonal = d3.svg.diagonal() - .projection(function (d) { return [d.y, d.x]; }); - var graphRoot = d3.select(root.dom).append("svg") - .attr("width", width + margin.left + margin.right); - var graph = graphRoot.append("g") - .attr("transform", "translate(" + margin.left + "," + margin.top + ")"); - var selected; - select(rootNode); - function update() { - var nodes = tree.nodes(rootNode); - var height = Math.max(500, nodes.length * barHeight + margin.top + margin.bottom); - d3.select("svg").transition() - .duration(duration) - .attr("height", height); - d3.select(self.frameElement).transition() - .duration(duration) - .style("height", height + "px"); - nodes.forEach(function (n, i) { - n.x = i * barHeight; - }); - var node = graph.selectAll("g.node") - .data(nodes, function (d) { return d.id || (d.id = ++i); }); - var nodeEnter = node.enter().append("g") - .attr("class", "node") - .attr("transform", function (d) { return "translate(" + rootNode.depth + "," + rootNode.nodeIndex + ")"; }) - .style("opacity", 1e-6); - nodeEnter.append("rect") - .attr("y", -barHeight / 2) - .attr("height", barHeight) - .attr("width", barWidth) - .style("fill", color) - .on("click", select); - nodeEnter.append("text") - .attr("dy", 3.5) - .attr("dx", 5.5) - .text(function (d) { - return d.kind; - }); - nodeEnter.transition() - .duration(duration) - .attr("transform", function (d) { return "translate(" + d.y + "," + d.x + ")"; }) - .style("opacity", 1); - node.transition() - .duration(duration) - .attr("transform", function (d) { return "translate(" + d.y + "," + d.x + ")"; }) - .style("opacity", 1) - .select("rect") - .style("fill", color); - node.exit().transition() - .duration(duration) - .attr("transform", function (d) { return "translate(" + rootNode.nodeIndex + "," + rootNode.depth + ")"; }) - .style("opacity", 1e-6) - .remove(); - var link = graph.selectAll("path.link") - .data(tree.links(nodes), function (d) { return d.target.id; }); - link.enter().insert("path", "g") - .attr("class", "link") - .attr("d", function (d) { - var o = { x: rootNode.depth, y: rootNode.nodeIndex }; - return diagonal({ source: o, target: o }); - }) - .transition() - .duration(duration) - .attr("d", diagonal); - link.transition() - .duration(duration) - .attr("d", diagonal); - link.exit().transition() - .duration(duration) - .attr("d", function (d) { - var o = { x: rootNode.depth, y: rootNode.nodeIndex }; - return diagonal({ source: o, target: o }); - }) - .remove(); - } - function resize() { - width = root.jq.width() - margin.left - margin.right; - d3.select("svg").attr("width", width); - update(); - } - d3.select(root.dom).on("resize", resize); - resize(); - function select(node) { - display(node); - selected = node; - update(); - } - function color(d) { - if (selected == d) { - return "rgb(140, 0, 0)"; - } - return d.children ? "#000000" : "rgb(29, 166, 0)"; - } -} diff --git a/dist/main/atom/views/awesomePanelView.js b/dist/main/atom/views/awesomePanelView.js deleted file mode 100644 index 93cb04a9c..000000000 --- a/dist/main/atom/views/awesomePanelView.js +++ /dev/null @@ -1,28 +0,0 @@ -"use strict"; -var __extends = (this && this.__extends) || function (d, b) { - for (var p in b) if (b.hasOwnProperty(p)) d[p] = b[p]; - function __() { this.constructor = d; } - d.prototype = b === null ? Object.create(b) : (__.prototype = b.prototype, new __()); -}; -var view = require("./view"); -var $ = view.$; -var AwesomePanelView = (function (_super) { - __extends(AwesomePanelView, _super); - function AwesomePanelView() { - return _super.apply(this, arguments) || this; - } - AwesomePanelView.content = function () { - var _this = this; - return this.div({ class: 'awesome' }, function () { return _this.div({ class: 'dude', outlet: 'something' }); }); - }; - AwesomePanelView.prototype.init = function () { - this.something.html('
tada
'); - }; - return AwesomePanelView; -}(view.View)); -exports.AwesomePanelView = AwesomePanelView; -function attach() { - exports.panelView = new AwesomePanelView({}); - exports.panel = atom.workspace.addModalPanel({ item: exports.panelView, priority: 1000, visible: false }); -} -exports.attach = attach; diff --git a/dist/main/atom/views/contextView.js b/dist/main/atom/views/contextView.js deleted file mode 100644 index 65bd020fe..000000000 --- a/dist/main/atom/views/contextView.js +++ /dev/null @@ -1,72 +0,0 @@ -"use strict"; -var __extends = (this && this.__extends) || function (d, b) { - for (var p in b) if (b.hasOwnProperty(p)) d[p] = b[p]; - function __() { this.constructor = d; } - d.prototype = b === null ? Object.create(b) : (__.prototype = b.prototype, new __()); -}; -var sp = require("atom-space-pen-views"); -var mainPanelView = require("./mainPanelView"); -var semanticView = require("./semanticView"); -var titles = { - togglePanel: 'Toggle TypeScript Panel', - tabErrors: 'Tab: Errors in Open Files', - tabLastBuild: 'Tab: Last Build Output', - tabReferences: 'Tab: Find References', - fileSemantics: 'Toggle: File Semantics', -}; -var items = Object.keys(titles).map(function (item) { return { title: titles[item] }; }); -var ContextView = (function (_super) { - __extends(ContextView, _super); - function ContextView() { - var _this = _super.apply(this, arguments) || this; - _this.panel = null; - return _this; - } - Object.defineProperty(ContextView.prototype, "$", { - get: function () { - return this; - }, - enumerable: true, - configurable: true - }); - ContextView.prototype.setItems = function (items) { _super.prototype.setItems.call(this, items); }; - ContextView.prototype.viewForItem = function (item) { - return "
  • " + item.title + "
  • "; - }; - ContextView.prototype.confirmed = function (item) { - if (item.title == titles.togglePanel) { - mainPanelView.panelView.toggle(); - } - if (item.title == titles.tabErrors) { - mainPanelView.panelView.errorPanelSelected(); - } - if (item.title == titles.tabLastBuild) { - mainPanelView.panelView.buildPanelSelected(); - } - if (item.title == titles.tabReferences) { - mainPanelView.panelView.referencesPanelSelected(); - } - if (item.title == titles.fileSemantics) { - semanticView.toggle(); - } - this.hide(); - }; - ContextView.prototype.getFilterKey = function () { return 'title'; }; - ContextView.prototype.show = function () { - this.storeFocusedElement(); - if (!this.panel) - this.panel = atom.workspace.addModalPanel({ item: this }); - this.panel.show(); - this.setItems(items); - this.focusFilterEditor(); - }; - ContextView.prototype.hide = function () { - this.panel.hide(); - this.restoreFocus(); - }; - ContextView.prototype.cancelled = function () { - this.hide(); - }; - return ContextView; -}(sp.SelectListView)); -exports.ContextView = ContextView; diff --git a/dist/main/atom/views/dependencyView.js b/dist/main/atom/views/dependencyView.js deleted file mode 100644 index ee5d6c744..000000000 --- a/dist/main/atom/views/dependencyView.js +++ /dev/null @@ -1,402 +0,0 @@ -"use strict"; -var __extends = (this && this.__extends) || function (d, b) { - for (var p in b) if (b.hasOwnProperty(p)) d[p] = b[p]; - function __() { this.constructor = d; } - d.prototype = b === null ? Object.create(b) : (__.prototype = b.prototype, new __()); -}; -var sp = require("atom-space-pen-views"); -var atomUtils = require("../atomUtils"); -var parent = require("../../../worker/parent"); -var d3 = require("d3"); -var path_1 = require("path"); -var fsUtil_1 = require("../../utils/fsUtil"); -var os = require("os"); -exports.dependencyURI = "ts-dependency:"; -var DependencyView = (function (_super) { - __extends(DependencyView, _super); - function DependencyView(filePath) { - var _this = _super.call(this) || this; - _this.filePath = filePath; - _this.getURI = function () { return atomUtils.uriForPath(exports.dependencyURI, _this.filePath); }; - _this.getTitle = function () { return 'TypeScript Dependencies'; }; - _this.getIconName = function () { return 'git-compare'; }; - _this.init(); - return _this; - } - DependencyView.content = function () { - return this.div({ class: 'dependency-view' }, function () { - }); - }; - Object.defineProperty(DependencyView.prototype, "$", { - get: function () { - return this; - }, - enumerable: true, - configurable: true - }); - DependencyView.prototype.init = function () { - var _this = this; - parent.getDependencies({ filePath: this.filePath }).then(function (res) { - renderGraph(res.links, _this.$, function (node) { - }); - }); - }; - return DependencyView; -}(sp.ScrollView)); -exports.DependencyView = DependencyView; -var prefixes = { - circle: 'circle' -}; -function renderGraph(dependencies, mainContent, display) { - var rootElement = mainContent[0]; - var d3Root = d3.select(rootElement); - rootElement.innerHTML = "\n
    \n
    \n \n \n
    \n
    \n \n \n
    \n
    \n \n
    \n
    \n
    "; - var messagesElement = mainContent.find('.general-messages'); - messagesElement.text("No Issues Found!"); - var filterElement = mainContent.find('#filter'); - filterElement.keyup(function (event) { - if (event.keyCode !== 13) { - return; - } - var val = filterElement.val().trim(); - if (!val) { - nodes.classed('filtered-out', false); - links.classed('filtered-out', false); - text.classed('filtered-out', false); - return; - } - else { - nodes.classed('filtered-out', true); - links.classed('filtered-out', true); - text.classed('filtered-out', true); - var filteredNodes = graph.selectAll("circle[data-name*=\"" + htmlName({ name: val }) + "\"]"); - filteredNodes.classed('filtered-out', false); - var filteredLinks = graph.selectAll("[data-source*=\"" + htmlName({ name: val }) + "\"][data-target*=\"" + htmlName({ name: val }) + "\"]"); - filteredLinks.classed('filtered-out', false); - var filteredText = graph.selectAll("text[data-name*=\"" + htmlName({ name: val }) + "\"]"); - filteredText.classed('filtered-out', false); - } - }); - var copyDisplay = mainContent.find('.copy-message>button'); - var d3NodeLookup = {}; - var d3links = dependencies.map(function (link) { - var source = d3NodeLookup[link.sourcePath] || (d3NodeLookup[link.sourcePath] = { name: link.sourcePath }); - var target = d3NodeLookup[link.targetPath] || (d3NodeLookup[link.targetPath] = { name: link.targetPath }); - return { source: source, target: target }; - }); - var d3Graph = new D3Graph(d3links); - if (d3Graph.cycles().length) { - var cycles = d3Graph.cycles(); - var message = ''; - var textContent_1 = ''; - for (var _i = 0, cycles_1 = cycles; _i < cycles_1.length; _i++) { - var cycle = cycles_1[_i]; - message += '

    Cycle Found:

    '; - message += cycle.join('
    ') + '
    '; - textContent_1 += '---Cycle Found---' + os.EOL; - textContent_1 += cycle.join(os.EOL) + os.EOL; - } - messagesElement.html(message); - copyDisplay.show().on('click', function () { - atom.clipboard.write(textContent_1); - atom.notifications.addInfo('Copied!'); - }); - } - else { - copyDisplay.hide(); - messagesElement.hide(); - } - Object.keys(d3NodeLookup).forEach(function (name) { - var node = d3NodeLookup[name]; - node.weight = d3Graph.avgDeg(node); - }); - var zoom = d3.behavior.zoom(); - zoom.scale(0.4); - zoom.on("zoom", onZoomChanged); - var graph = d3Root.append("svg") - .attr('width', '100%') - .attr('height', '99%') - .call(zoom) - .append('svg:g'); - var layout = d3.layout.force() - .nodes(d3.values(d3NodeLookup)) - .links(d3links) - .gravity(.05) - .linkDistance(function (link) { return (d3Graph.difference(link)) * 200; }) - .charge(-900) - .on("tick", tick) - .start(); - var drag = layout.drag() - .on("dragstart", dragstart); - resize(); - d3.select(window).on("resize", resize); - centerGraph(); - var graphWidth, graphHeight; - function resize() { - graphWidth = mainContent.width(); - graphHeight = mainContent.height(); - graph.attr("width", graphWidth) - .attr("height", graphHeight); - layout.size([graphWidth, graphHeight]) - .resume(); - } - function centerGraph() { - var centerTranslate = [ - (graphWidth / 4), - (graphHeight / 4), - ]; - zoom.translate(centerTranslate); - graph.transition() - .duration(500) - .attr("transform", "translate(" + zoom.translate() + ")" + " scale(" + zoom.scale() + ")"); - } - function onZoomChanged() { - graph.attr("transform", "translate(" + d3.event.translate + ")" + " scale(" + d3.event.scale + ")"); - } - graph.append("defs").selectAll("marker") - .data(["regular"]) - .enter().append("marker") - .attr("id", function (d) { return d; }) - .attr("viewBox", "0 -5 10 10") - .attr("refX", 15) - .attr("refY", -1.5) - .attr("markerWidth", 6) - .attr("markerHeight", 6) - .attr("orient", "auto") - .append("path") - .attr("d", "M0,-5L10,0L0,5"); - var links = graph.append("g").selectAll("path") - .data(layout.links()) - .enter().append("path") - .attr("class", function (d) { return "link"; }) - .attr("data-target", function (o) { return htmlName(o.target); }) - .attr("data-source", function (o) { return htmlName(o.source); }) - .attr("marker-end", function (d) { return "url(#regular)"; }); - var nodes = graph.append("g").selectAll("circle") - .data(layout.nodes()) - .enter().append("circle") - .attr("class", function (d) { return formatClassName(prefixes.circle, d); }) - .attr("data-name", function (o) { return htmlName(o); }) - .attr("r", function (d) { return Math.max(d.weight, 3); }) - .classed("inonly", function (d) { return d3Graph.inOnly(d); }) - .classed("outonly", function (d) { return d3Graph.outOnly(d); }) - .classed("circular", function (d) { return d3Graph.isCircular(d); }) - .call(drag) - .on("dblclick", dblclick) - .on("mouseover", function (d) { onNodeMouseOver(d); }) - .on("mouseout", function (d) { onNodeMouseOut(d); }); - var text = graph.append("g").selectAll("text") - .data(layout.nodes()) - .enter().append("text") - .attr("x", 8) - .attr("y", ".31em") - .attr("data-name", function (o) { return htmlName(o); }) - .text(function (d) { return d.name; }); - function tick() { - links.attr("d", linkArc); - nodes.attr("transform", transform); - text.attr("transform", transform); - } - function transform(d) { - return "translate(" + d.x + "," + d.y + ")"; - } - function onNodeMouseOver(d) { - var elm = findElementByNode(prefixes.circle, d); - elm.classed("hovering", true); - updateNodeTransparencies(d, true); - } - function onNodeMouseOut(d) { - var elm = findElementByNode(prefixes.circle, d); - elm.classed("hovering", false); - updateNodeTransparencies(d, false); - } - function findElementByNode(prefix, node) { - var selector = '.' + formatClassName(prefix, node); - return graph.select(selector); - } - function updateNodeTransparencies(d, fade) { - if (fade === void 0) { fade = true; } - nodes.classed('not-hovering', false); - nodes.classed('dimmed', false); - if (fade) { - nodes.each(function (o) { - if (!d3Graph.isConnected(d, o)) { - this.classList.add('not-hovering'); - this.classList.add('dimmed'); - } - }); - } - graph.selectAll('path.link').attr('data-show', '') - .classed('outgoing', false) - .attr('marker-end', fade ? '' : 'url(#regular)') - .classed('incomming', false) - .classed('dimmed', fade); - links.each(function (o) { - if (o.source.name === d.name) { - this.classList.remove('dimmed'); - var elmNodes = graph.selectAll('.' + formatClassName(prefixes.circle, o.target)); - elmNodes.attr('fill-opacity', 1); - elmNodes.attr('stroke-opacity', 1); - elmNodes.classed('dimmed', false); - var outgoingLink = graph.selectAll('path.link[data-source="' + htmlName(o.source) + '"]'); - outgoingLink.attr('data-show', 'true'); - outgoingLink.attr('marker-end', 'url(#regular)'); - outgoingLink.classed('outgoing', true); - } - else if (o.target.name === d.name) { - this.classList.remove('dimmed'); - var incommingLink = graph.selectAll('path.link[data-target="' + htmlName(o.target) + '"]'); - incommingLink.attr('data-show', 'true'); - incommingLink.attr('marker-end', 'url(#regular)'); - incommingLink.classed('incomming', true); - } - }); - text.classed("dimmed", function (o) { - if (!fade) - return false; - if (d3Graph.isConnected(d, o)) - return false; - return true; - }); - } - function formatClassName(prefix, object) { - return prefix + '-' + htmlName(object); - } - function htmlName(object) { - return object.name.replace(/(\.|\/)/gi, '-'); - } - function dragstart(d) { - d.fixed = true; - d3.event.sourceEvent.stopPropagation(); - d3.select(this).classed("fixed", true); - } - function dblclick(d) { - d3.select(this).classed("fixed", d.fixed = false); - } -} -var D3Graph = (function () { - function D3Graph(links) { - var _this = this; - this.links = links; - this.inDegLookup = {}; - this.outDegLookup = {}; - this.linkedByName = {}; - this.targetsBySourceName = {}; - this.circularPaths = []; - links.forEach(function (l) { - if (!_this.inDegLookup[l.target.name]) - _this.inDegLookup[l.target.name] = 2; - else - _this.inDegLookup[l.target.name]++; - if (!_this.outDegLookup[l.source.name]) - _this.outDegLookup[l.source.name] = 2; - else - _this.outDegLookup[l.source.name]++; - _this.linkedByName[l.source.name + "," + l.target.name] = 1; - if (!_this.targetsBySourceName[l.source.name]) - _this.targetsBySourceName[l.source.name] = []; - _this.targetsBySourceName[l.source.name].push(l.target); - }); - this.findCircular(); - } - D3Graph.prototype.inDeg = function (node) { - return this.inDegLookup[node.name] ? this.inDegLookup[node.name] : 1; - }; - D3Graph.prototype.outDeg = function (node) { - return this.outDegLookup[node.name] ? this.outDegLookup[node.name] : 1; - }; - D3Graph.prototype.avgDeg = function (node) { - return (this.inDeg(node) + this.outDeg(node)) / 2; - }; - D3Graph.prototype.isConnected = function (a, b) { - return this.linkedByName[a.name + "," + b.name] || this.linkedByName[b.name + "," + a.name] || a.name == b.name; - }; - D3Graph.prototype.difference = function (link) { - return fsUtil_1.consistentPath(path_1.relative(link.source.name, link.target.name)).split('/').length; - }; - D3Graph.prototype.inOnly = function (node) { - return !this.outDegLookup[node.name] && this.inDegLookup[node.name]; - }; - D3Graph.prototype.outOnly = function (node) { - return !this.inDegLookup[node.name] && this.outDegLookup[node.name]; - }; - D3Graph.prototype.getPath = function (parent, unresolved) { - var parentVisited = false; - return Object.keys(unresolved).filter(function (module) { - if (module === parent.name) { - parentVisited = true; - } - return parentVisited && unresolved[module]; - }); - }; - D3Graph.prototype.resolver = function (sourceName, resolved, unresolved) { - var _this = this; - unresolved[sourceName] = true; - if (this.targetsBySourceName[sourceName]) { - this.targetsBySourceName[sourceName].forEach(function (dependency) { - if (!resolved[dependency.name]) { - if (unresolved[dependency.name]) { - _this.circularPaths.push(_this.getPath(dependency, unresolved)); - return; - } - _this.resolver(dependency.name, resolved, unresolved); - } - }); - } - resolved[sourceName] = true; - unresolved[sourceName] = false; - }; - D3Graph.prototype.findCircular = function () { - var _this = this; - var resolved = {}, unresolved = {}; - Object.keys(this.targetsBySourceName).forEach(function (sourceName) { - _this.resolver(sourceName, resolved, unresolved); - }); - }; - ; - D3Graph.prototype.isCircular = function (node) { - var cyclic = false; - this.circularPaths.some(function (path) { - if (path.indexOf(node.name) >= 0) { - cyclic = true; - return true; - } - return false; - }); - return cyclic; - }; - D3Graph.prototype.cycles = function () { - return this.circularPaths; - }; - return D3Graph; -}()); -function linkArc(d) { - var targetX = d.target.x; - var targetY = d.target.y; - var sourceX = d.source.x; - var sourceY = d.source.y; - var theta = Math.atan((targetX - sourceX) / (targetY - sourceY)); - var phi = Math.atan((targetY - sourceY) / (targetX - sourceX)); - var sinTheta = d.source.weight / 2 * Math.sin(theta); - var cosTheta = d.source.weight / 2 * Math.cos(theta); - var sinPhi = (d.target.weight - 6) * Math.sin(phi); - var cosPhi = (d.target.weight - 6) * Math.cos(phi); - if (d.target.y > d.source.y) { - sourceX = sourceX + sinTheta; - sourceY = sourceY + cosTheta; - } - else { - sourceX = sourceX - sinTheta; - sourceY = sourceY - cosTheta; - } - if (d.source.x > d.target.x) { - targetX = targetX + cosPhi; - targetY = targetY + sinPhi; - } - else { - targetX = targetX - cosPhi; - targetY = targetY - sinPhi; - } - var dx = targetX - sourceX, dy = targetY - sourceY, dr = Math.sqrt(dx * dx + dy * dy); - return "M" + sourceX + "," + sourceY + "A" + dr + "," + dr + " 0 0,1 " + targetX + "," + targetY; -} diff --git a/dist/main/atom/views/documentationView.js b/dist/main/atom/views/documentationView.js deleted file mode 100644 index 221fcd27a..000000000 --- a/dist/main/atom/views/documentationView.js +++ /dev/null @@ -1,66 +0,0 @@ -"use strict"; -var __extends = (this && this.__extends) || function (d, b) { - for (var p in b) if (b.hasOwnProperty(p)) d[p] = b[p]; - function __() { this.constructor = d; } - d.prototype = b === null ? Object.create(b) : (__.prototype = b.prototype, new __()); -}; -var view = require("./view"); -var $ = view.$; -var DocumentationView = (function (_super) { - __extends(DocumentationView, _super); - function DocumentationView() { - var _this = _super.apply(this, arguments) || this; - _this.shown = false; - return _this; - } - DocumentationView.content = function () { - var _this = this; - return this.div({ class: 'atom-ts-documentation padded top' }, function () { return _this.div(function () { - _this.h2({ outlet: 'header' }); - _this.p({ outlet: 'documentation' }); - }); }); - }; - DocumentationView.prototype.show = function () { this.$.addClass('active'); this.shown = true; }; - DocumentationView.prototype.hide = function () { this.$.removeClass('active'); this.shown = false; }; - DocumentationView.prototype.toggle = function () { if (this.shown) { - this.hide(); - } - else { - this.show(); - } }; - DocumentationView.prototype.setContent = function (content) { - this.header.html(content.display); - content.documentation = content.documentation.replace(/(?:\r\n|\r|\n)/g, '
    '); - this.documentation.html(content.documentation); - }; - DocumentationView.prototype.autoPosition = function () { - var editor = atom.workspace.getActiveTextEditor(); - var cursor = editor.getCursors()[0]; - var cursorTop = cursor.getPixelRect().top - editor.getScrollTop(); - var editorHeight = editor.getHeight(); - if (editorHeight - cursorTop < 100) { - this.$.removeClass('bottom'); - this.$.addClass('top'); - } - else { - this.$.removeClass('top'); - this.$.addClass('bottom'); - } - }; - return DocumentationView; -}(view.View)); -exports.DocumentationView = DocumentationView; -function attach() { - if (exports.docView) - return; - exports.docView = new DocumentationView({}); - $(atom.views.getView(atom.workspace)).append(exports.docView.$); -} -exports.attach = attach; -function testDocumentationView() { - exports.docView.setContent({ - display: "this is awesome", documentation: "\n some docs\n over\n many\n many li\n\n lines\n long\n so\n long\n that\n it\n should\n\n start\n to\n scroll\n ", filePath: "some filepath" - }); - exports.docView.show(); -} -exports.testDocumentationView = testDocumentationView; diff --git a/dist/main/atom/views/fileSemanticView.js b/dist/main/atom/views/fileSemanticView.js deleted file mode 100644 index 10294de0a..000000000 --- a/dist/main/atom/views/fileSemanticView.js +++ /dev/null @@ -1,32 +0,0 @@ -var __extends = (this && this.__extends) || function (d, b) { - for (var p in b) if (b.hasOwnProperty(p)) d[p] = b[p]; - function __() { this.constructor = d; } - d.prototype = b === null ? Object.create(b) : (__.prototype = b.prototype, new __()); -}; -var atomUtils = require("../atomUtils"); -function showForCurrentEditor() { - var ed = atomUtils.getActiveEditor(); - showForEditor(ed); -} -exports.showForCurrentEditor = showForCurrentEditor; -function showForEditor(ed) { - // atom.notifications.addInfo('Semantic view coming soon'); -} -exports.showForEditor = showForEditor; -var view_1 = require("./view"); -var FileSemanticView = (function (_super) { - __extends(FileSemanticView, _super); - function FileSemanticView(options) { - _super.call(this, options); - } - FileSemanticView.prototype.init = function () { - var _this = this; - this.stopChangingListener = this.options.editor.onDidStopChanging(function () { - }); - this.destroyListener = this.options.editor.onDidDestroy(function () { - _this.destroyListener.dispose(); - _this.stopChangingListener.dispose(); - }); - }; - return FileSemanticView; -})(view_1.ScrollView); diff --git a/dist/main/atom/views/fileSymbolsView.js b/dist/main/atom/views/fileSymbolsView.js deleted file mode 100644 index ceee0f7e7..000000000 --- a/dist/main/atom/views/fileSymbolsView.js +++ /dev/null @@ -1,55 +0,0 @@ -"use strict"; -var __extends = (this && this.__extends) || function (d, b) { - for (var p in b) if (b.hasOwnProperty(p)) d[p] = b[p]; - function __() { this.constructor = d; } - d.prototype = b === null ? Object.create(b) : (__.prototype = b.prototype, new __()); -}; -var sp = require("atom-space-pen-views"); -var atomUtils = require("../atomUtils"); -var FileSymbolsView = (function (_super) { - __extends(FileSymbolsView, _super); - function FileSymbolsView() { - var _this = _super.apply(this, arguments) || this; - _this.panel = null; - return _this; - } - Object.defineProperty(FileSymbolsView.prototype, "$", { - get: function () { - return this; - }, - enumerable: true, - configurable: true - }); - FileSymbolsView.prototype.setNavBarItems = function (tsItems, filePath) { - var items = tsItems; - this.filePath = filePath; - _super.prototype.setItems.call(this, items); - }; - FileSymbolsView.prototype.viewForItem = function (item) { - return "\n
  • \n
    " + (Array(item.indent * 2).join(' ') + (item.indent ? "\u221F " : '') + item.text) + "
    \n
    " + item.kind + "
    \n
    line: " + (item.position.line + 1) + "
    \n
  • \n "; - }; - FileSymbolsView.prototype.confirmed = function (item) { - atom.workspace.open(this.filePath, { - initialLine: item.position.line, - initialColumn: item.position.col - }); - this.hide(); - }; - FileSymbolsView.prototype.getFilterKey = function () { return 'text'; }; - FileSymbolsView.prototype.show = function () { - this.storeFocusedElement(); - if (!this.panel) - this.panel = atom.workspace.addModalPanel({ item: this }); - this.panel.show(); - this.focusFilterEditor(); - }; - FileSymbolsView.prototype.hide = function () { - this.panel.hide(); - this.restoreFocus(); - }; - FileSymbolsView.prototype.cancelled = function () { - this.hide(); - }; - return FileSymbolsView; -}(sp.SelectListView)); -exports.FileSymbolsView = FileSymbolsView; diff --git a/dist/main/atom/views/lineMessageView.js b/dist/main/atom/views/lineMessageView.js deleted file mode 100644 index e7d373ebb..000000000 --- a/dist/main/atom/views/lineMessageView.js +++ /dev/null @@ -1,71 +0,0 @@ -"use strict"; -var __extends = (this && this.__extends) || function (d, b) { - for (var p in b) if (b.hasOwnProperty(p)) d[p] = b[p]; - function __() { this.constructor = d; } - d.prototype = b === null ? Object.create(b) : (__.prototype = b.prototype, new __()); -}; -var view = require("./view"); -var $ = view.$; -var LineMessageView = (function (_super) { - __extends(LineMessageView, _super); - function LineMessageView() { - return _super.apply(this, arguments) || this; - } - LineMessageView.content = function () { - var _this = this; - return this.div({ - class: 'line-message' - }, function () { - _this.div({ - class: 'text-subtle inline-block', - outlet: 'position', - click: 'goToLine', - style: 'cursor: pointer;' - }); - _this.div({ - class: 'message inline-block', - outlet: 'contents' - }); - _this.pre({ - class: 'preview', - outlet: 'code', - click: 'goToLine', - style: 'cursor: pointer;' - }); - }); - }; - LineMessageView.prototype.init = function () { - var message = 'at line ' + this.options.line; - if (this.options.file !== undefined) { - message += ', file ' + this.options.file; - } - this.position.text(message); - this.contents.text(this.options.message); - if (this.options.preview) { - this.code.text(this.options.preview); - } - else { - this.code.remove(); - } - }; - LineMessageView.prototype.goToLine = function () { - this.options.goToLine(this.options.file, this.options.line, this.options.col); - }; - LineMessageView.prototype.getSummary = function () { - var pos = this.options.line.toString(); - if (this.options.file !== undefined) { - pos += ', ' + this.options.file; - } - return { - summary: pos + ' ' + this.options.message, - rawSummary: true, - handler: function (element) { - $(element) - .css('cursor', 'pointer') - .click(this.goToLine.bind(this)); - }.bind(this) - }; - }; - return LineMessageView; -}(view.View)); -exports.LineMessageView = LineMessageView; diff --git a/dist/main/atom/views/mainPanelView.js b/dist/main/atom/views/mainPanelView.js deleted file mode 100644 index f67ae3637..000000000 --- a/dist/main/atom/views/mainPanelView.js +++ /dev/null @@ -1,478 +0,0 @@ -"use strict"; -var __extends = (this && this.__extends) || function (d, b) { - for (var p in b) if (b.hasOwnProperty(p)) d[p] = b[p]; - function __() { this.constructor = d; } - d.prototype = b === null ? Object.create(b) : (__.prototype = b.prototype, new __()); -}; -var view = require("./view"); -var $ = view.$; -var lineMessageView = require("./lineMessageView"); -var atomUtils = require("../atomUtils"); -var parent = require("../../../worker/parent"); -var utils = require("../../lang/utils"); -var fileStatusCache_1 = require("../fileStatusCache"); -var panelHeaders = { - error: 'Errors In Open Files', - build: 'Last Build Output', - references: 'References' -}; -var gotoHistory = require("../gotoHistory"); -var MainPanelView = (function (_super) { - __extends(MainPanelView, _super); - function MainPanelView() { - var _this = _super.apply(this, arguments) || this; - _this.pendingRequests = []; - _this.expanded = false; - _this.clearedError = true; - return _this; - } - MainPanelView.content = function () { - var _this = this; - var btn = function (view, text, className) { - if (className === void 0) { className = ''; } - return _this.button({ - 'class': "btn btn-sm " + className, - 'click': view + "PanelSelectedClick", - 'outlet': view + "PanelBtn" - }, text); - }; - this.div({ - class: 'atomts atomts-main-panel-view native-key-bindings', - tabindex: '-1' - }, function () { - _this.div({ - class: 'layout horizontal', - style: '-webkit-user-select: none; flex-wrap: wrap', - dblclick: 'toggle' - }, function () { - _this.span({ - class: 'layout horizontal atomts-panel-header', - style: 'align-items: center' - }, function () { - _this.span({ - style: 'cursor: pointer; color: rgb(0, 148, 255); -webkit-user-select: none; white-space: nowrap; overflow: hidden; text-overflow: ellipsis; min-width: 16px', - click: 'toggle' - }, function () { - _this.span({ class: 'icon-microscope' }); - _this.span({ style: 'font-weight: bold' }, 'TypeScript'); - }); - _this.div({ - class: 'btn-group', - style: 'margin-left: 6px; flex: 1 0 auto' - }, function () { - btn('error', panelHeaders.error, 'selected'); - btn('build', panelHeaders.build); - btn('references', panelHeaders.references); - }); - }); - _this.span({ - class: 'layout horizontal atomts-panel-header', - style: 'align-items: center; flex: 1 1 auto; line-height: 24px;' - }, function () { - _this.div({ - style: 'cursor: pointer;', - click: 'clickedCurrentTsconfigFilePath' - }, function () { - _this.span({ - outlet: 'tsconfigInUse' - }); - }); - _this.div({ - style: 'overflow-x: visible; white-space: nowrap;' - }, function () { - _this.span({ - style: 'margin-left: 10px; transition: color 1s', - outlet: 'fileStatus' - }); - }); - _this.div({ - class: 'heading-summary flex', - style: 'margin-left: 5px; overflow: hidden; white-space:nowrap; text-overflow: ellipsis', - outlet: 'summary' - }); - _this.progress({ - class: 'inline-block build-progress', - style: 'display: none; color: red', - outlet: 'buildProgress' - }); - _this.span({ - class: 'section-pending', - outlet: 'sectionPending', - click: 'showPending' - }, function () { - _this.span({ - outlet: 'txtPendingCount', - style: 'cursor: pointer; margin-left: 5px', - }); - _this.span({ - class: 'loading loading-spinner-tiny inline-block', - style: 'cursor: pointer; margin-left: 5px' - }); - }); - _this.div({ - class: 'heading-buttons', - style: 'margin-left: 5px' - }, function () { - _this.span({ - class: 'heading-fold icon-unfold', - style: 'cursor: pointer; margin-right: 10px', - outlet: 'btnFold', - click: 'toggle' - }); - _this.span({ - class: 'heading-fold icon-sync', - style: 'cursor: pointer', - outlet: 'btnSoftReset', - click: 'softReset' - }); - }); - }); - _this.div({ - class: 'panel-body atomts-panel-body', - outlet: 'errorBody', - style: 'overflow-y: auto; flex: 1 0 100%; display: none' - }); - _this.div({ - class: 'panel-body atomts-panel-body', - outlet: 'buildBody', - style: 'overflow-y: auto; flex: 1 0 100%; display: none' - }); - _this.div({ - class: 'panel-body atomts-panel-body', - outlet: 'referencesBody', - style: 'overflow-y: auto; flex: 1 0 100%; display: none' - }); - }); - }); - }; - MainPanelView.prototype.init = function () { - this.buildPanelBtn.html(panelHeaders.build + " ( No Build )"); - this.buildBody.html(' No Build. Press ( F12 ) to start a build for an active TypeScript file\'s project. '); - this.referencesPanelBtn.html(panelHeaders.references + " ( No Search )"); - this.referencesBody.html(' You haven\'t searched for TypeScript references yet. '); - }; - MainPanelView.prototype.softReset = function () { - var editor = atom.workspace.getActiveTextEditor(); - var prom = parent.softReset({ filePath: editor.getPath(), text: editor.getText() }) - .then(function () { - }); - if (atomUtils.onDiskAndTs(editor)) { - prom.then(function () { - atomUtils.triggerLinter(); - return parent.errorsForFile({ filePath: editor.getPath() }); - }) - .then(function (resp) { return errorView.setErrors(editor.getPath(), resp.errors); }); - } - }; - MainPanelView.prototype.setTsconfigInUse = function (tsconfigFilePath) { - this.fullTsconfigPath = tsconfigFilePath; - if (!this.fullTsconfigPath) { - this.tsconfigInUse.text('no tsconfig.json'); - } - else { - var path = atomUtils.getFilePathRelativeToAtomProject(tsconfigFilePath); - this.tsconfigInUse.text("" + path); - } - }; - MainPanelView.prototype.clickedCurrentTsconfigFilePath = function () { - if (!this.fullTsconfigPath) { - atom.notifications.addInfo("No tsconfig for current file"); - return; - } - else { - atomUtils.openFile(this.fullTsconfigPath); - } - }; - MainPanelView.prototype.updateFileStatus = function (filePath) { - var _this = this; - parent.getProjectFileDetails({ filePath: filePath }).then(function (fileDetails) { - if (!fileDetails.project.compileOnSave) { - _this.fileStatus.addClass("hidden"); - } - else { - var status_1 = fileStatusCache_1.getFileStatus(filePath); - _this.fileStatus.removeClass('icon-x icon-check text-error text-success hidden'); - if (status_1.emitDiffers || status_1.modified) { - _this.fileStatus.text('JS Outdated'); - _this.fileStatus.addClass('icon-x text-error'); - } - else { - _this.fileStatus.text('JS Current'); - _this.fileStatus.addClass('icon-check text-success'); - } - } - }); - }; - MainPanelView.prototype.showPending = function () { - atom.notifications.addInfo('Pending Requests:
    - ' + this.pendingRequests.join('
    - ')); - }; - MainPanelView.prototype.updatePendingRequests = function (pending) { - this.pendingRequests = pending; - this.txtPendingCount.html("" + this.pendingRequests.length + ""); - this.sectionPending.stop(); - if (pending.length) { - this.sectionPending.animate({ opacity: 0.5 }, 500); - } - else { - this.sectionPending.animate({ opacity: 0 }, 200); - } - }; - MainPanelView.prototype.errorPanelSelectedClick = function () { - this.toggleIfThisIsntSelected(this.errorPanelBtn); - this.errorPanelSelected(); - }; - MainPanelView.prototype.errorPanelSelected = function () { - this.selectPanel(this.errorPanelBtn, this.errorBody, gotoHistory.errorsInOpenFiles); - }; - MainPanelView.prototype.buildPanelSelectedClick = function () { - this.toggleIfThisIsntSelected(this.buildPanelBtn); - this.buildPanelSelected(); - }; - MainPanelView.prototype.buildPanelSelected = function () { - this.selectPanel(this.buildPanelBtn, this.buildBody, gotoHistory.buildOutput); - }; - MainPanelView.prototype.referencesPanelSelectedClick = function () { - this.toggleIfThisIsntSelected(this.referencesPanelBtn); - this.referencesPanelSelected(); - }; - MainPanelView.prototype.referencesPanelSelected = function (forceExpand) { - if (forceExpand === void 0) { forceExpand = false; } - this.selectPanel(this.referencesPanelBtn, this.referencesBody, gotoHistory.referencesOutput); - }; - MainPanelView.prototype.toggleIfThisIsntSelected = function (btn) { - if (btn.hasClass('selected')) { - this.expanded = !this.expanded; - } - }; - MainPanelView.prototype.selectPanel = function (btn, body, activeList) { - var _this = this; - var buttons = [this.errorPanelBtn, this.buildPanelBtn, this.referencesPanelBtn]; - var bodies = [this.errorBody, this.buildBody, this.referencesBody]; - buttons.forEach(function (b) { - if (b !== btn) - b.removeClass('selected'); - else - b.addClass('selected'); - }); - bodies.forEach(function (b) { - if (!_this.expanded) { - b.hide('fast'); - } - else { - if (b !== body) - b.hide('fast'); - else { - body.show('fast'); - } - } - }); - gotoHistory.activeList = activeList; - gotoHistory.activeList.lastPosition = null; - }; - MainPanelView.prototype.setActivePanel = function () { - if (this.errorPanelBtn.hasClass('selected')) { - this.errorPanelSelected(); - } - if (this.buildPanelBtn.hasClass('selected')) { - this.buildPanelSelected(); - } - if (this.referencesPanelBtn.hasClass('selected')) { - this.referencesPanelSelected(); - } - }; - MainPanelView.prototype.toggle = function () { - this.expanded = !this.expanded; - this.setActivePanel(); - }; - MainPanelView.prototype.setReferences = function (references) { - this.referencesPanelSelected(true); - this.referencesBody.empty(); - if (references.length == 0) { - var title = panelHeaders.references + " ( No References )"; - this.referencesPanelBtn.html(title); - this.referencesBody.html('No references found \u2665'); - atom.notifications.addInfo('AtomTS: No References Found.'); - return; - } - var title = panelHeaders.references + " ( Found: " + references.length + " )"; - this.referencesPanelBtn.html(title); - gotoHistory.referencesOutput.members = []; - for (var _i = 0, references_1 = references; _i < references_1.length; _i++) { - var ref = references_1[_i]; - var view = new lineMessageView.LineMessageView({ - goToLine: function (filePath, line, col) { return gotoHistory.gotoLine(filePath, line, col, gotoHistory.referencesOutput); }, - message: '', - line: ref.position.line + 1, - col: ref.position.col, - file: ref.filePath, - preview: ref.preview - }); - this.referencesBody.append(view.$); - gotoHistory.referencesOutput.members.push({ filePath: ref.filePath, line: ref.position.line + 1, col: ref.position.col }); - } - }; - MainPanelView.prototype.clearError = function () { - this.clearedError = true; - this.clearSummary(); - this.errorBody.empty(); - }; - MainPanelView.prototype.addError = function (view) { - if (this.clearedError && view.getSummary) { - this.setErrorSummary(view.getSummary()); - } - this.clearedError = false; - this.errorBody.append(view.$); - }; - MainPanelView.prototype.setErrorSummary = function (summary) { - var message = summary.summary, className = summary.className, raw = summary.rawSummary || false, handler = summary.handler || undefined; - this.summary.html(message); - if (className) { - this.summary.addClass(className); - } - if (handler) { - handler(this.summary); - } - }; - MainPanelView.prototype.clearSummary = function () { - this.summary.html(''); - this.summary.off(); - }; - MainPanelView.prototype.setErrorPanelErrorCount = function (fileErrorCount, totalErrorCount) { - var title = panelHeaders.error + " ( No Errors )"; - if (totalErrorCount > 0) { - title = panelHeaders.error + " (\n " + fileErrorCount + " \n file" + (fileErrorCount === 1 ? "" : "s") + " \n " + totalErrorCount + " \n error" + (totalErrorCount === 1 ? "" : "s") + " \n )"; - } - else { - this.clearSummary(); - this.errorBody.html('No errors in open files \u2665'); - } - this.errorPanelBtn.html(title); - }; - MainPanelView.prototype.setBuildPanelCount = function (errorCount, inProgressBuild) { - if (inProgressBuild === void 0) { inProgressBuild = false; } - var titleMain = inProgressBuild ? "Build Progress" : panelHeaders.build; - var title = titleMain + " ( No Errors )"; - if (errorCount > 0) { - title = titleMain + " (\n " + errorCount + " \n error" + (errorCount === 1 ? "" : "s") + " \n )"; - } - else { - if (!inProgressBuild) - this.buildBody.html('No errors in last build \u2665'); - } - this.buildPanelBtn.html(title); - }; - MainPanelView.prototype.clearBuild = function () { - this.buildBody.empty(); - }; - MainPanelView.prototype.addBuild = function (view) { - this.buildBody.append(view.$); - }; - MainPanelView.prototype.setBuildProgress = function (progress) { - var _this = this; - if (progress.builtCount == 1) { - this.buildProgress.show(); - this.buildProgress.removeClass('warn'); - this.buildBody.html('Things are looking good \u2665'); - gotoHistory.buildOutput.members = []; - } - if (progress.builtCount == progress.totalCount) { - this.buildProgress.hide(); - return; - } - this.buildProgress.prop('value', progress.builtCount); - this.buildProgress.prop('max', progress.totalCount); - this.setBuildPanelCount(progress.errorCount, true); - if (progress.firstError) { - this.buildProgress.addClass('warn'); - this.clearBuild(); - } - if (progress.errorsInFile.length) { - progress.errorsInFile.forEach(function (error) { - _this.addBuild(new lineMessageView.LineMessageView({ - goToLine: function (filePath, line, col) { return gotoHistory.gotoLine(filePath, line, col, gotoHistory.buildOutput); }, - message: error.message, - line: error.startPos.line + 1, - col: error.startPos.col, - file: error.filePath, - preview: error.preview - })); - gotoHistory.buildOutput.members.push({ filePath: error.filePath, line: error.startPos.line + 1, col: error.startPos.col }); - }); - } - }; - return MainPanelView; -}(view.View)); -exports.MainPanelView = MainPanelView; -var panel; -function attach() { - if (exports.panelView) - return; - exports.panelView = new MainPanelView({}); - panel = atom.workspace.addBottomPanel({ item: exports.panelView, priority: 1000, visible: true }); - exports.panelView.setErrorPanelErrorCount(0, 0); -} -exports.attach = attach; -function show() { - if (!exports.panelView) - return; - exports.panelView.$.show(); -} -exports.show = show; -function hide() { - if (!exports.panelView) - return; - exports.panelView.$.hide(); -} -exports.hide = hide; -var errorView; -(function (errorView) { - var MAX_ERRORS = 50; - var filePathErrors = new utils.Dict(); - errorView.setErrors = function (filePath, errorsForFile) { - if (!exports.panelView || !exports.panelView.clearError) { - return; - } - if (!errorsForFile.length) { - filePathErrors.clearValue(filePath); - } - else { - if (errorsForFile.length > MAX_ERRORS) { - errorsForFile = errorsForFile.slice(0, MAX_ERRORS); - } - filePathErrors.setValue(filePath, errorsForFile); - } - exports.panelView.clearError(); - var fileErrorCount = filePathErrors.keys().length; - gotoHistory.errorsInOpenFiles.members = []; - if (!fileErrorCount) { - exports.panelView.setErrorPanelErrorCount(0, 0); - } - else { - var totalErrorCount = 0; - for (var path in filePathErrors.table) { - filePathErrors.getValue(path).forEach(function (error) { - totalErrorCount++; - exports.panelView.addError(new lineMessageView.LineMessageView({ - goToLine: function (filePath, line, col) { return gotoHistory.gotoLine(filePath, line, col, gotoHistory.errorsInOpenFiles); }, - message: error.message, - line: error.startPos.line + 1, - col: error.startPos.col, - file: error.filePath, - preview: error.preview - })); - gotoHistory.errorsInOpenFiles.members.push({ filePath: error.filePath, line: error.startPos.line + 1, col: error.startPos.col }); - }); - } - exports.panelView.setErrorPanelErrorCount(fileErrorCount, totalErrorCount); - } - }; - function showEmittedMessage(output) { - if (output.emitError) { - atom.notifications.addError('TS Emit Failed'); - } - else if (!output.success) { - atomUtils.quickNotifyWarning('Compile failed but emit succeeded
    ' + output.outputFiles.join('
    ')); - } - } - errorView.showEmittedMessage = showEmittedMessage; -})(errorView = exports.errorView || (exports.errorView = {})); diff --git a/dist/main/atom/views/plainMessageView.js b/dist/main/atom/views/plainMessageView.js deleted file mode 100644 index 18bc8eff6..000000000 --- a/dist/main/atom/views/plainMessageView.js +++ /dev/null @@ -1,32 +0,0 @@ -"use strict"; -var __extends = (this && this.__extends) || function (d, b) { - for (var p in b) if (b.hasOwnProperty(p)) d[p] = b[p]; - function __() { this.constructor = d; } - d.prototype = b === null ? Object.create(b) : (__.prototype = b.prototype, new __()); -}; -var view = require("./view"); -var $ = view.$; -var PlainMessageView = (function (_super) { - __extends(PlainMessageView, _super); - function PlainMessageView() { - return _super.apply(this, arguments) || this; - } - PlainMessageView.content = function () { - this.div({ - class: 'plain-message' - }); - }; - PlainMessageView.prototype.init = function () { - this.$.html(this.options.message); - this.$.addClass(this.options.className); - }; - PlainMessageView.prototype.getSummary = function () { - return { - summary: this.options.message, - rawSummary: true, - className: this.options.className - }; - }; - return PlainMessageView; -}(view.View)); -exports.PlainMessageView = PlainMessageView; diff --git a/dist/main/atom/views/projectSymbolsView.js b/dist/main/atom/views/projectSymbolsView.js deleted file mode 100644 index c97754181..000000000 --- a/dist/main/atom/views/projectSymbolsView.js +++ /dev/null @@ -1,65 +0,0 @@ -"use strict"; -var __extends = (this && this.__extends) || function (d, b) { - for (var p in b) if (b.hasOwnProperty(p)) d[p] = b[p]; - function __() { this.constructor = d; } - d.prototype = b === null ? Object.create(b) : (__.prototype = b.prototype, new __()); -}; -var sp = require("atom-space-pen-views"); -var atomUtils = require("../atomUtils"); -var ProjectSymbolsView = (function (_super) { - __extends(ProjectSymbolsView, _super); - function ProjectSymbolsView() { - var _this = _super.apply(this, arguments) || this; - _this.panel = null; - return _this; - } - Object.defineProperty(ProjectSymbolsView.prototype, "$", { - get: function () { - return this; - }, - enumerable: true, - configurable: true - }); - Object.defineProperty(ProjectSymbolsView.prototype, "filterView", { - get: function () { - return { - $: this.filterEditorView, - model: this.filterEditorView.model - }; - }, - enumerable: true, - configurable: true - }); - ProjectSymbolsView.prototype.setNavBarItems = function (tsItems) { - _super.prototype.setMaxItems.call(this, 40); - var items = tsItems; - _super.prototype.setItems.call(this, items); - }; - ProjectSymbolsView.prototype.viewForItem = function (item) { - return "\n
  • \n
    " + item.name + "
    \n
    " + item.kind + "
    \n
    " + item.fileName + " : " + (item.position.line + 1) + "
    \n
  • \n "; - }; - ProjectSymbolsView.prototype.confirmed = function (item) { - atom.workspace.open(item.filePath, { - initialLine: item.position.line, - initialColumn: item.position.col - }); - this.hide(); - }; - ProjectSymbolsView.prototype.getFilterKey = function () { return 'name'; }; - ProjectSymbolsView.prototype.show = function () { - this.storeFocusedElement(); - if (!this.panel) - this.panel = atom.workspace.addModalPanel({ item: this }); - this.panel.show(); - this.focusFilterEditor(); - }; - ProjectSymbolsView.prototype.hide = function () { - this.panel.hide(); - this.restoreFocus(); - }; - ProjectSymbolsView.prototype.cancelled = function () { - this.hide(); - }; - return ProjectSymbolsView; -}(sp.SelectListView)); -exports.ProjectSymbolsView = ProjectSymbolsView; diff --git a/dist/main/atom/views/rView.js b/dist/main/atom/views/rView.js deleted file mode 100644 index b1b34d01f..000000000 --- a/dist/main/atom/views/rView.js +++ /dev/null @@ -1,66 +0,0 @@ -"use strict"; -var __extends = (this && this.__extends) || function (d, b) { - for (var p in b) if (b.hasOwnProperty(p)) d[p] = b[p]; - function __() { this.constructor = d; } - d.prototype = b === null ? Object.create(b) : (__.prototype = b.prototype, new __()); -}; -var atomUtils_1 = require("../atomUtils"); -var sp = require("atom-space-pen-views"); -var React = require("react"); -var MyComponent = (function (_super) { - __extends(MyComponent, _super); - function MyComponent(props) { - var _this = _super.call(this, props) || this; - _this.state = { count: 0 }; - _this.stop = function () { - clearInterval(_this.interval); - }; - return _this; - } - MyComponent.prototype.componentDidMount = function () { - var _this = this; - this.interval = setInterval(function () { - _this.setState({ count: _this.state.count + 1 }); - }); - }; - MyComponent.prototype.render = function () { - return React.createElement("div", { onClick: this.stop }, - "This is a test: ", - this.state.count); - }; - return MyComponent; -}(React.Component)); -MyComponent.defaultProps = { count: 0 }; -var RView = (function (_super) { - __extends(RView, _super); - function RView(config) { - var _this = _super.call(this) || this; - _this.config = config; - _this.getURI = function () { return atomUtils_1.uriForPath(_this.constructor.protocol, _this.config.filePath); }; - _this.getTitle = function () { return _this.config.title; }; - _this.getIconName = function () { return _this.config.icon; }; - React.render(React.createElement(MyComponent, {}), _this.rootDomElement); - return _this; - } - Object.defineProperty(RView.prototype, "rootDomElement", { - get: function () { - return this.mainContent[0]; - }, - enumerable: true, - configurable: true - }); - RView.content = function () { - var _this = this; - return this.div({ class: 'atomts atomts-r-view native-key-bindings' }, function () { - _this.div({ outlet: 'mainContent layout' }); - }); - }; - Object.defineProperty(RView.prototype, "$", { - get: function () { return this; }, - enumerable: true, - configurable: true - }); - return RView; -}(sp.ScrollView)); -RView.protocol = 'atomtsview:'; -exports.RView = RView; diff --git a/dist/main/atom/views/renameView.js b/dist/main/atom/views/renameView.js index 9c3bc3bd0..27d0cf935 100644 --- a/dist/main/atom/views/renameView.js +++ b/dist/main/atom/views/renameView.js @@ -1,84 +1,91 @@ "use strict"; -var __extends = (this && this.__extends) || function (d, b) { - for (var p in b) if (b.hasOwnProperty(p)) d[p] = b[p]; - function __() { this.constructor = d; } - d.prototype = b === null ? Object.create(b) : (__.prototype = b.prototype, new __()); -}; -var view = require("./view"); +Object.defineProperty(exports, "__esModule", { value: true }); +const view = require("./view"); var $ = view.$; var html = require('../../../../views/renameView.html'); -var RenameView = (function (_super) { - __extends(RenameView, _super); - function RenameView() { - var _this = _super.apply(this, arguments) || this; - _this.editorAtRenameStart = null; - return _this; - } - RenameView.prototype.init = function () { - var _this = this; - $(atom.views.getView(atom.workspace)).on('keydown', function (e) { +class RenameView extends view.View { + init() { + $(atom.views.getView(atom.workspace)).on('keydown', (e) => { if (e.keyCode == 27) { - if (_this.options.onCancel) { - _this.options.onCancel(); - _this.clearView(); + if (this.options.onCancel) { + this.options.onCancel(); + this.clearView(); } } }); - this.newNameEditor.on('keydown', function (e) { - var newText = _this.newNameEditor.model.getText(); + this.newNameEditor.on('keydown', (e) => { + var newText = this.newNameEditor.model.getText(); if (e.keyCode == 13) { - var invalid = _this.options.onValidate(newText); + var invalid = this.options.onValidate(newText); if (invalid) { - _this.validationMessage.text(invalid); - _this.validationMessage.show(); + this.validationMessage.text(invalid); + this.validationMessage.show(); return; } - _this.validationMessage.hide(); - if (_this.options.onCommit) { - _this.options.onCommit(newText); - _this.clearView(); + this.validationMessage.hide(); + if (this.options.onCommit) { + this.options.onCommit(newText); + this.clearView(); } } if (e.keyCode == 27) { - if (_this.options.onCancel) { - _this.options.onCancel(); - _this.clearView(); + if (this.options.onCancel) { + this.options.onCancel(); + this.clearView(); } } }); - }; - RenameView.prototype.clearView = function () { + } + setPanel(panel) { + this.panel = panel; + } + clearView() { if (this.editorAtRenameStart && !this.editorAtRenameStart.isDestroyed()) { var view = atom.views.getView(this.editorAtRenameStart); view.focus(); } - panel.hide(); + this.panel.hide(); this.options = {}; - this.editorAtRenameStart = null; - }; - RenameView.prototype.renameThis = function (options) { + this.editorAtRenameStart = undefined; + } + renameThis(options) { this.options = options; this.editorAtRenameStart = atom.workspace.getActiveTextEditor(); - panel.show(); + this.panel.show(); this.newNameEditor.model.setText(options.text); if (this.options.autoSelect) { this.newNameEditor.model.selectAll(); } else { - this.newNameEditor.model.moveToEndOfScreenLine(); + this.newNameEditor.model.moveCursorToEndOfScreenLine(); } this.title.text(this.options.title); this.newNameEditor.focus(); this.validationMessage.hide(); - this.fileCount.html("
    \n Files Counts: Already Open ( " + options.openFiles.length + " ) and Currently Closed ( " + options.closedFiles.length + " ) \n
    "); - }; - return RenameView; -}(view.View)); + } + // Show the dialog and resolve the promise with the entered string + showRenameDialog(options) { + return new Promise((resolve, reject) => { + this.renameThis(Object.assign({}, options, { onCancel: reject, onCommit: resolve })); + }); + } +} RenameView.content = html; exports.RenameView = RenameView; -var panel; function attach() { - exports.panelView = new RenameView({}); - panel = atom.workspace.addModalPanel({ item: exports.panelView, priority: 1000, visible: false }); + const renameView = new RenameView({}); + const panel = atom.workspace.addModalPanel({ + item: renameView, + priority: 1000, + visible: false + }); + renameView.setPanel(panel); + return { + dispose() { + console.log("TODO: Detach the rename view: ", panel); + }, + renameView + }; } exports.attach = attach; +//# sourceMappingURL=renameView.js.map \ No newline at end of file diff --git a/dist/main/atom/views/renameView.js.map b/dist/main/atom/views/renameView.js.map new file mode 100644 index 000000000..1754dbc60 --- /dev/null +++ b/dist/main/atom/views/renameView.js.map @@ -0,0 +1 @@ +{"version":3,"file":"renameView.js","sourceRoot":"","sources":["../../../../lib/main/atom/views/renameView.ts"],"names":[],"mappings":";;AAAA,+BAAgC;AAChC,IAAI,CAAC,GAAG,IAAI,CAAC,CAAC,CAAC;AACf,IAAI,IAAI,GAAG,OAAO,CAAC,mCAAmC,CAAC,CAAC;AAgBxD,gBAAwB,SAAQ,IAAI,CAAC,IAAuB;IAQjD,IAAI;QACP,CAAC,CAAC,IAAI,CAAC,KAAK,CAAC,OAAO,CAAC,IAAI,CAAC,SAAS,CAAC,CAAC,CAAC,EAAE,CAAC,SAAS,EAAE,CAAC,CAAC;YAClD,EAAE,CAAC,CAAC,CAAC,CAAC,OAAO,IAAI,EAAE,CAAC,CAAC,CAAC;gBAClB,EAAE,CAAC,CAAC,IAAI,CAAC,OAAO,CAAC,QAAQ,CAAC,CAAC,CAAC;oBACxB,IAAI,CAAC,OAAO,CAAC,QAAQ,EAAE,CAAC;oBACxB,IAAI,CAAC,SAAS,EAAE,CAAC;gBACrB,CAAC;YACL,CAAC;QACL,CAAC,CAAC,CAAC;QAEH,IAAI,CAAC,aAAa,CAAC,EAAE,CAAC,SAAS,EAAE,CAAC,CAAC;YAC/B,IAAI,OAAO,GAAG,IAAI,CAAC,aAAa,CAAC,KAAK,CAAC,OAAO,EAAE,CAAC;YACjD,EAAE,CAAC,CAAC,CAAC,CAAC,OAAO,IAAI,EAAE,CAAC,CAAC,CAAC;gBAClB,IAAI,OAAO,GAAG,IAAI,CAAC,OAAO,CAAC,UAAU,CAAC,OAAO,CAAC,CAAC;gBAC/C,EAAE,CAAC,CAAC,OAAO,CAAC,CAAC,CAAC;oBACV,IAAI,CAAC,iBAAiB,CAAC,IAAI,CAAC,OAAO,CAAC,CAAC;oBACrC,IAAI,CAAC,iBAAiB,CAAC,IAAI,EAAE,CAAC;oBAC9B,MAAM,CAAC;gBACX,CAAC;gBACD,IAAI,CAAC,iBAAiB,CAAC,IAAI,EAAE,CAAC;gBAE9B,EAAE,CAAC,CAAC,IAAI,CAAC,OAAO,CAAC,QAAQ,CAAC,CAAC,CAAC;oBACxB,IAAI,CAAC,OAAO,CAAC,QAAQ,CAAC,OAAO,CAAC,CAAC;oBAC/B,IAAI,CAAC,SAAS,EAAE,CAAC;gBACrB,CAAC;YACL,CAAC;YACD,EAAE,CAAC,CAAC,CAAC,CAAC,OAAO,IAAI,EAAE,CAAC,CAAC,CAAC;gBAClB,EAAE,CAAC,CAAC,IAAI,CAAC,OAAO,CAAC,QAAQ,CAAC,CAAC,CAAC;oBACxB,IAAI,CAAC,OAAO,CAAC,QAAQ,EAAE,CAAC;oBACxB,IAAI,CAAC,SAAS,EAAE,CAAC;gBACrB,CAAC;YACL,CAAC;QACL,CAAC,CAAC,CAAC;IACP,CAAC;IAEM,QAAQ,CAAC,KAAqB;QACnC,IAAI,CAAC,KAAK,GAAG,KAAK,CAAA;IACpB,CAAC;IAGM,SAAS;QACZ,EAAE,CAAC,CAAC,IAAI,CAAC,mBAAmB,IAAI,CAAC,IAAI,CAAC,mBAAmB,CAAC,WAAW,EAAE,CAAC,CAAC,CAAC;YACtE,IAAI,IAAI,GAAG,IAAI,CAAC,KAAK,CAAC,OAAO,CAAC,IAAI,CAAC,mBAAmB,CAAC,CAAC;YACxD,IAAI,CAAC,KAAK,EAAE,CAAC;QACjB,CAAC;QACD,IAAI,CAAC,KAAK,CAAC,IAAI,EAAE,CAAC;QAClB,IAAI,CAAC,OAAO,GAAQ,EAAE,CAAC;QACvB,IAAI,CAAC,mBAAmB,GAAG,SAAS,CAAC;IACzC,CAAC;IAEO,UAAU,CAAC,OAA0B;QACzC,IAAI,CAAC,OAAO,GAAG,OAAO,CAAC;QACvB,IAAI,CAAC,mBAAmB,GAAG,IAAI,CAAC,SAAS,CAAC,mBAAmB,EAAE,CAAC;QAChE,IAAI,CAAC,KAAK,CAAC,IAAI,EAAE,CAAC;QAElB,IAAI,CAAC,aAAa,CAAC,KAAK,CAAC,OAAO,CAAC,OAAO,CAAC,IAAI,CAAC,CAAC;QAC/C,EAAE,CAAC,CAAC,IAAI,CAAC,OAAO,CAAC,UAAU,CAAC,CAAC,CAAC;YAC1B,IAAI,CAAC,aAAa,CAAC,KAAK,CAAC,SAAS,EAAE,CAAC;QACzC,CAAC;QACD,IAAI,CAAC,CAAC;YACF,IAAI,CAAC,aAAa,CAAC,KAAK,CAAC,2BAA2B,EAAE,CAAC;QAC3D,CAAC;QACD,IAAI,CAAC,KAAK,CAAC,IAAI,CAAC,IAAI,CAAC,OAAO,CAAC,KAAK,CAAC,CAAC;QACpC,IAAI,CAAC,aAAa,CAAC,KAAK,EAAE,CAAC;QAE3B,IAAI,CAAC,iBAAiB,CAAC,IAAI,EAAE,CAAC;IAClC,CAAC;IAED,kEAAkE;IAClE,gBAAgB,CAAC,OAA0B;QACzC,MAAM,CAAC,IAAI,OAAO,CAAC,CAAC,OAAO,EAAE,MAAM;YACjC,IAAI,CAAC,UAAU,mBACV,OAAO,IACV,QAAQ,EAAE,MAAM,EAChB,QAAQ,EAAE,OAAO,IACjB,CAAA;QACJ,CAAC,CAAC,CAAA;IACJ,CAAC;;AA/EM,kBAAO,GAAG,IAAI,CAAC;AAN1B,gCAsFC;AAED;IACI,MAAM,UAAU,GAAG,IAAI,UAAU,CAAM,EAAE,CAAC,CAAC;IAC3C,MAAM,KAAK,GAAG,IAAI,CAAC,SAAS,CAAC,aAAa,CAAC;QACzC,IAAI,EAAE,UAAU;QAChB,QAAQ,EAAE,IAAI;QACd,OAAO,EAAE,KAAK;KACf,CAAC,CAAA;IAEF,UAAU,CAAC,QAAQ,CAAC,KAAK,CAAC,CAAA;IAE1B,MAAM,CAAC;QACL,OAAO;YACL,OAAO,CAAC,GAAG,CAAC,gCAAgC,EAAE,KAAK,CAAC,CAAA;QACtD,CAAC;QACD,UAAU;KACX,CAAA;AACL,CAAC;AAhBD,wBAgBC"} \ No newline at end of file diff --git a/dist/main/atom/views/semanticView.js b/dist/main/atom/views/semanticView.js deleted file mode 100644 index 24dffb763..000000000 --- a/dist/main/atom/views/semanticView.js +++ /dev/null @@ -1,157 +0,0 @@ -"use strict"; -var __extends = (this && this.__extends) || function (d, b) { - for (var p in b) if (b.hasOwnProperty(p)) d[p] = b[p]; - function __() { this.constructor = d; } - d.prototype = b === null ? Object.create(b) : (__.prototype = b.prototype, new __()); -}; -var atomConfig = require("../atomConfig"); -var atomUtils = require("../atomUtils"); -var sp = require("atom-space-pen-views"); -var React = require("react"); -var parent = require("../../../worker/parent"); -var rts; -(function (rts) { - function indent(indent) { - return Array(indent + 1).join().split('').map(function (i) { return "\u00a0\u00a0\u00a0\u00a0"; }); - } - rts.indent = indent; -})(rts || (rts = {})); -var MyComponent = (function (_super) { - __extends(MyComponent, _super); - function MyComponent(props) { - var _this = _super.call(this, props) || this; - _this.whileRendering = { - lastCursorLine: null - }; - _this.state = { - tree: [] - }; - return _this; - } - MyComponent.prototype.componentDidMount = function () { - var _this = this; - var editorScrolling; - var editorChanging; - var subscribeToEditor = function (editor) { - _this.setState({ editor: editor }); - parent.getSemtanticTree({ filePath: editor.getPath() }).then(function (res) { - _this.setState({ tree: res.nodes }); - }); - editorScrolling = editor.onDidChangeCursorPosition(function () { - _this.forceUpdate(); - }); - editorChanging = editor.onDidStopChanging(function () { - parent.getSemtanticTree({ filePath: editor.getPath() }).then(function (res) { - _this.setState({ tree: res.nodes }); - }); - }); - panel.show(); - }; - var unsubscribeToEditor = function () { - panel.hide(); - _this.setState({ tree: [] }); - if (!_this.state.editor) - return; - editorScrolling.dispose(); - editorChanging.dispose(); - _this.forceUpdate(); - }; - subscribeToEditor(atomUtils.getActiveEditor()); - atom.workspace.onDidChangeActivePaneItem(function (editor) { - if (atomUtils.onDiskAndTs(editor) && atomConfig.showSemanticView) { - subscribeToEditor(editor); - } - else { - unsubscribeToEditor(); - } - }); - }; - MyComponent.prototype.componentWillUnmount = function () { - }; - MyComponent.prototype.render = function () { - var _this = this; - this.whileRendering = { - lastCursorLine: this.state.editor && this.state.editor.getLastCursor() ? this.state.editor.getLastCursor().getBufferRow() : null - }; - return React.createElement("div", null, this.state.tree.map(function (node) { return _this.renderNode(node, 0); })); - }; - MyComponent.prototype.renderNode = function (node, indent) { - var _this = this; - return React.createElement("div", { className: "node", onClick: function (event) { _this.gotoNode(node); event.stopPropagation(); }, "data-start": node.start.line, "data-end": node.end.line }, - rts.indent(indent), - React.createElement("span", { className: this.getIconForKind(node.kind) + ' ' + this.isSelected(node) }, node.text), - node.subNodes.map(function (sn) { return _this.renderNode(sn, indent + 1); })); - }; - MyComponent.prototype.getIconForKind = function (kind) { - return "icon icon-" + kind; - }; - MyComponent.prototype.isSelected = function (node) { - if (this.whileRendering.lastCursorLine == null) - return ''; - else { - if (node.start.line <= this.whileRendering.lastCursorLine && node.end.line >= this.whileRendering.lastCursorLine) { - return 'selected'; - } - return ''; - } - }; - MyComponent.prototype.gotoNode = function (node) { - var gotoLine = node.start.line; - this.state.editor.setCursorBufferPosition([gotoLine, 0]); - }; - return MyComponent; -}(React.Component)); -var SemanticView = (function (_super) { - __extends(SemanticView, _super); - function SemanticView(config) { - var _this = _super.call(this, config) || this; - _this.config = config; - _this.started = false; - return _this; - } - Object.defineProperty(SemanticView.prototype, "rootDomElement", { - get: function () { - return this.mainContent[0]; - }, - enumerable: true, - configurable: true - }); - SemanticView.content = function () { - var _this = this; - return this.div({ class: 'atomts atomts-semantic-view native-key-bindings' }, function () { - _this.div({ outlet: 'mainContent', class: 'layout vertical' }); - }); - }; - SemanticView.prototype.start = function () { - if (this.started) - return; - this.started = true; - React.render(React.createElement(MyComponent, {}), this.rootDomElement); - }; - return SemanticView; -}(sp.ScrollView)); -exports.SemanticView = SemanticView; -var panel; -function attach() { - if (exports.mainView) { - return; - } - exports.mainView = new SemanticView({}); - panel = atom.workspace.addRightPanel({ item: exports.mainView, priority: 1000, visible: atomConfig.showSemanticView && atomUtils.isActiveEditorOnDiskAndTs() }); - if (panel.isVisible()) { - exports.mainView.start(); - } -} -exports.attach = attach; -function toggle() { - if (panel.isVisible()) { - atomConfig.showSemanticView = (false); - panel.hide(); - } - else { - atomConfig.showSemanticView = (true); - panel.show(); - exports.mainView.start(); - } -} -exports.toggle = toggle; diff --git a/dist/main/atom/views/simpleOverlaySelectionView.js b/dist/main/atom/views/simpleOverlaySelectionView.js deleted file mode 100644 index 87c4ffef4..000000000 --- a/dist/main/atom/views/simpleOverlaySelectionView.js +++ /dev/null @@ -1,68 +0,0 @@ -"use strict"; -var __extends = (this && this.__extends) || function (d, b) { - for (var p in b) if (b.hasOwnProperty(p)) d[p] = b[p]; - function __() { this.constructor = d; } - d.prototype = b === null ? Object.create(b) : (__.prototype = b.prototype, new __()); -}; -var singleton; -function default_1(options, editor) { - if (!singleton) - singleton = new SimpleOverlaySelectListView(options, editor); - else { - singleton.options = options; - singleton.editor = editor; - } - singleton.setItems(); - singleton.show(); - return singleton; -} -Object.defineProperty(exports, "__esModule", { value: true }); -exports.default = default_1; -var sp = require("atom-space-pen-views"); -var SimpleOverlaySelectListView = (function (_super) { - __extends(SimpleOverlaySelectListView, _super); - function SimpleOverlaySelectListView(options, editor) { - var _this = _super.call(this) || this; - _this.options = options; - _this.editor = editor; - _this.$.addClass('atomts-overlay'); - _this.filterEditorView.model.placeholderText = 'Filter list'; - return _this; - } - Object.defineProperty(SimpleOverlaySelectListView.prototype, "$", { - get: function () { - return this; - }, - enumerable: true, - configurable: true - }); - SimpleOverlaySelectListView.prototype.setItems = function () { - _super.prototype.setItems.call(this, this.options.items); - }; - SimpleOverlaySelectListView.prototype.viewForItem = function (item) { - return "
  • \n " + this.options.viewForItem(item) + "\n
  • "; - }; - SimpleOverlaySelectListView.prototype.confirmed = function (item) { - this.options.confirmed(item); - this.hide(); - }; - SimpleOverlaySelectListView.prototype.getFilterKey = function () { - return this.options.filterKey; - }; - SimpleOverlaySelectListView.prototype.show = function () { - var _this = this; - this.storeFocusedElement(); - this._overlayDecoration = this.editor.decorateMarker(this.editor.getLastCursor().getMarker(), { type: "overlay", position: "tail", item: this }); - setTimeout(function () { return _this.focusFilterEditor(); }, 100); - }; - SimpleOverlaySelectListView.prototype.hide = function () { - this.restoreFocus(); - if (this._overlayDecoration) - this._overlayDecoration.destroy(); - }; - SimpleOverlaySelectListView.prototype.cancelled = function () { - this.hide(); - }; - return SimpleOverlaySelectListView; -}(sp.SelectListView)); -exports.SimpleOverlaySelectListView = SimpleOverlaySelectListView; diff --git a/dist/main/atom/views/simpleSelectionView.js b/dist/main/atom/views/simpleSelectionView.js index a05fd18df..d481291da 100644 --- a/dist/main/atom/views/simpleSelectionView.js +++ b/dist/main/atom/views/simpleSelectionView.js @@ -1,9 +1,9 @@ +/** + * A functional form of the SelectListView + * Only one of these bad boys is allowed on the screen at one time + */ "use strict"; -var __extends = (this && this.__extends) || function (d, b) { - for (var p in b) if (b.hasOwnProperty(p)) d[p] = b[p]; - function __() { this.constructor = d; } - d.prototype = b === null ? Object.create(b) : (__.prototype = b.prototype, new __()); -}; +Object.defineProperty(exports, "__esModule", { value: true }); var singleton; function simpleSelectionView(options) { if (!singleton) @@ -16,57 +16,61 @@ function simpleSelectionView(options) { return singleton; } exports.simpleSelectionView = simpleSelectionView; -var sp = require("atom-space-pen-views"); +/** + * Various Utility section + */ +const sp = require("atom-space-pen-views"); var $ = sp.$; -var SimpleSelectListView = (function (_super) { - __extends(SimpleSelectListView, _super); - function SimpleSelectListView(options) { - var _this = _super.call(this) || this; - _this.options = options; - _this.panel = null; - return _this; +class SimpleSelectListView extends sp.SelectListView { + constructor(options) { + super(); + this.options = options; } - Object.defineProperty(SimpleSelectListView.prototype, "$", { - get: function () { - return this; - }, - enumerable: true, - configurable: true - }); - SimpleSelectListView.prototype.setItems = function () { - _super.prototype.setItems.call(this, this.options.items); - }; - SimpleSelectListView.prototype.viewForItem = function (item) { + get $() { + return this; + } + setItems() { + super.setItems(this.options.items); + } + /** override */ + viewForItem(item) { var view = this.options.viewForItem(item); if (typeof view === "string") { - return "
  • \n " + view + "\n
  • "; + return `
  • + ${view} +
  • `; } else { return $('
  • ').append(view); } ; - }; - SimpleSelectListView.prototype.confirmed = function (item) { + } + /** override */ + confirmed(item) { this.options.confirmed(item); this.hide(); - }; - SimpleSelectListView.prototype.getFilterKey = function () { + } + /** override */ + getFilterKey() { return this.options.filterKey; - }; - SimpleSelectListView.prototype.show = function () { + } + show() { this.storeFocusedElement(); if (!this.panel) this.panel = atom.workspace.addModalPanel({ item: this }); this.panel.show(); this.focusFilterEditor(); - }; - SimpleSelectListView.prototype.hide = function () { - this.panel.hide(); + // debugger; // DEBUG: the UI in the inspector so that it doesn't change on you + } + hide() { + if (this.panel) { + this.panel.hide(); + } this.restoreFocus(); - }; - SimpleSelectListView.prototype.cancelled = function () { + } + cancelled() { this.hide(); - }; - return SimpleSelectListView; -}(sp.SelectListView)); + } +} exports.SimpleSelectListView = SimpleSelectListView; +//# sourceMappingURL=simpleSelectionView.js.map \ No newline at end of file diff --git a/dist/main/atom/views/simpleSelectionView.js.map b/dist/main/atom/views/simpleSelectionView.js.map new file mode 100644 index 000000000..9aec24ab0 --- /dev/null +++ b/dist/main/atom/views/simpleSelectionView.js.map @@ -0,0 +1 @@ +{"version":3,"file":"simpleSelectionView.js","sourceRoot":"","sources":["../../../../lib/main/atom/views/simpleSelectionView.ts"],"names":[],"mappings":"AAAA;;;GAGG;;;AAYH,IAAI,SAAoC,CAAC;AAEzC,6BAAuC,OAAiC;IACpE,EAAE,CAAC,CAAC,CAAC,SAAS,CAAC;QAAC,SAAS,GAAG,IAAI,oBAAoB,CAAI,OAAO,CAAC,CAAC;IACjE,IAAI,CAAC,CAAC;QAAC,SAAS,CAAC,OAAO,GAAG,OAAO,CAAC;IAAC,CAAC;IAErC,SAAS,CAAC,QAAQ,EAAE,CAAC;IACrB,SAAS,CAAC,IAAI,EAAE,CAAC;IACjB,MAAM,CAAC,SAAS,CAAC;AACrB,CAAC;AAPD,kDAOC;AAED;;GAEG;AAEH,2CAA4C;AAC5C,IAAO,CAAC,GAAG,EAAE,CAAC,CAAC,CAAC;AAEhB,0BAAqC,SAAQ,EAAE,CAAC,cAAc;IAE1D,YAAmB,OAAiC;QAChD,KAAK,EAAE,CAAC;QADO,YAAO,GAAP,OAAO,CAA0B;IAEpD,CAAC;IAED,IAAI,CAAC;QACD,MAAM,CAAM,IAAI,CAAC;IACrB,CAAC;IAEM,QAAQ;QACX,KAAK,CAAC,QAAQ,CAAC,IAAI,CAAC,OAAO,CAAC,KAAK,CAAC,CAAA;IACtC,CAAC;IAED,eAAe;IACf,WAAW,CAAC,IAAO;QACf,IAAI,IAAI,GAAG,IAAI,CAAC,OAAO,CAAC,WAAW,CAAC,IAAI,CAAC,CAAC;QAC1C,EAAE,CAAC,CAAC,OAAO,IAAI,KAAK,QAAQ,CAAC,CAAC,CAAC;YAC3B,MAAM,CAAC;kBACD,IAAI;kBACJ,CAAC;QACX,CAAC;QACD,IAAI,CAAC,CAAC;YACF,MAAM,CAAC,CAAC,CAAC,WAAW,CAAC,CAAC,MAAM,CAAC,IAAI,CAAC,CAAC;QACvC,CAAC;QAAA,CAAC;IACN,CAAC;IAED,eAAe;IACf,SAAS,CAAC,IAAO;QACb,IAAI,CAAC,OAAO,CAAC,SAAS,CAAC,IAAI,CAAC,CAAC;QAC7B,IAAI,CAAC,IAAI,EAAE,CAAC;IAChB,CAAC;IAED,eAAe;IACf,YAAY;QACR,MAAM,CAAC,IAAI,CAAC,OAAO,CAAC,SAAS,CAAC;IAClC,CAAC;IAGD,IAAI;QACA,IAAI,CAAC,mBAAmB,EAAE,CAAC;QAC3B,EAAE,CAAC,CAAC,CAAC,IAAI,CAAC,KAAK,CAAC;YAAC,IAAI,CAAC,KAAK,GAAG,IAAI,CAAC,SAAS,CAAC,aAAa,CAAC,EAAE,IAAI,EAAE,IAAI,EAAE,CAAC,CAAC;QAC3E,IAAI,CAAC,KAAK,CAAC,IAAI,EAAE,CAAA;QAEjB,IAAI,CAAC,iBAAiB,EAAE,CAAC;QACzB,+EAA+E;IACnF,CAAC;IACD,IAAI;QACF,EAAE,CAAC,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC,CAAC;YACf,IAAI,CAAC,KAAK,CAAC,IAAI,EAAE,CAAA;QACnB,CAAC;QAED,IAAI,CAAC,YAAY,EAAE,CAAA;IACrB,CAAC;IAED,SAAS;QACL,IAAI,CAAC,IAAI,EAAE,CAAC;IAChB,CAAC;CACJ;AA1DD,oDA0DC"} \ No newline at end of file diff --git a/dist/main/atom/views/tooltipView.js b/dist/main/atom/views/tooltipView.js index dd297a53d..9c28bb44c 100644 --- a/dist/main/atom/views/tooltipView.js +++ b/dist/main/atom/views/tooltipView.js @@ -1,36 +1,30 @@ "use strict"; -var __extends = (this && this.__extends) || function (d, b) { - for (var p in b) if (b.hasOwnProperty(p)) d[p] = b[p]; - function __() { this.constructor = d; } - d.prototype = b === null ? Object.create(b) : (__.prototype = b.prototype, new __()); -}; -var view = require("./view"); +Object.defineProperty(exports, "__esModule", { value: true }); +const view = require("./view"); var $ = view.$; -var TooltipView = (function (_super) { - __extends(TooltipView, _super); - function TooltipView(rect) { - var _this = _super.call(this, rect) || this; - _this.rect = rect; - $(document.body).append(_this.$); - _this.updatePosition(); - return _this; +class TooltipView extends view.View { + constructor(rect) { + super(rect); + this.rect = rect; + $(document.body).append(this.$); + this.updatePosition(); } - TooltipView.content = function () { - var _this = this; - return this.div({ class: 'atom-typescript-tooltip tooltip' }, function () { - _this.div({ class: 'tooltip-inner', outlet: 'inner' }); + static content() { + return this.div({ class: 'atom-typescript-tooltip tooltip' }, () => { + this.div({ class: 'tooltip-inner', outlet: 'inner' }); }); - }; - TooltipView.prototype.updateText = function (text) { + } + updateText(text) { this.inner.html(text); this.updatePosition(); this.$.fadeTo(300, 1); - }; - TooltipView.prototype.updatePosition = function () { + } + updatePosition() { var offset = 10; var left = this.rect.right; var top = this.rect.bottom; var right = undefined; + // X axis adjust if (left + this.$[0].offsetWidth >= view.$(document.body).width()) left = view.$(document.body).width() - this.$[0].offsetWidth - offset; if (left < 0) { @@ -38,11 +32,12 @@ var TooltipView = (function (_super) { left = offset; right = offset; } + // Y axis adjust if (top + this.$[0].offsetHeight >= $(document.body).height()) { top = this.rect.top - this.$[0].offsetHeight; } - this.$.css({ left: left, top: top, right: right }); - }; - return TooltipView; -}(view.View)); + this.$.css({ left, top, right }); + } +} exports.TooltipView = TooltipView; +//# sourceMappingURL=tooltipView.js.map \ No newline at end of file diff --git a/dist/main/atom/views/tooltipView.js.map b/dist/main/atom/views/tooltipView.js.map new file mode 100644 index 000000000..94a8a69f6 --- /dev/null +++ b/dist/main/atom/views/tooltipView.js.map @@ -0,0 +1 @@ +{"version":3,"file":"tooltipView.js","sourceRoot":"","sources":["../../../../lib/main/atom/views/tooltipView.ts"],"names":[],"mappings":";;AAAA,+BAAgC;AAChC,IAAI,CAAC,GAAG,IAAI,CAAC,CAAC,CAAC;AASf,iBAAyB,SAAQ,IAAI,CAAC,IAAU;IAE5C,YAAmB,IAAU;QACzB,KAAK,CAAC,IAAI,CAAC,CAAC;QADG,SAAI,GAAJ,IAAI,CAAM;QAEzB,CAAC,CAAC,QAAQ,CAAC,IAAI,CAAC,CAAC,MAAM,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;QAChC,IAAI,CAAC,cAAc,EAAE,CAAA;IACzB,CAAC;IAGD,MAAM,CAAC,OAAO;QACV,MAAM,CAAC,IAAI,CAAC,GAAG,CAAC,EAAE,KAAK,EAAE,iCAAiC,EAAE,EAAE;YAC1D,IAAI,CAAC,GAAG,CAAC,EAAE,KAAK,EAAE,eAAe,EAAE,MAAM,EAAE,OAAO,EAAE,CAAC,CAAA;QACzD,CAAC,CAAC,CAAC;IACP,CAAC;IAED,UAAU,CAAC,IAAY;QACnB,IAAI,CAAC,KAAK,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;QACtB,IAAI,CAAC,cAAc,EAAE,CAAC;QACtB,IAAI,CAAC,CAAC,CAAC,MAAM,CAAC,GAAG,EAAE,CAAC,CAAC,CAAC;IAC1B,CAAC;IAED,cAAc;QACV,IAAI,MAAM,GAAG,EAAE,CAAC;QAChB,IAAI,IAAI,GAAG,IAAI,CAAC,IAAI,CAAC,KAAK,CAAC;QAC3B,IAAI,GAAG,GAAG,IAAI,CAAC,IAAI,CAAC,MAAM,CAAC;QAC3B,IAAI,KAAK,GAAuB,SAAS,CAAC;QAE1C,gBAAgB;QAChB,EAAE,CAAC,CAAC,IAAI,GAAG,IAAI,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,WAAW,IAAI,IAAI,CAAC,CAAC,CAAC,QAAQ,CAAC,IAAI,CAAC,CAAC,KAAK,EAAE,CAAC;YAC9D,IAAI,GAAG,IAAI,CAAC,CAAC,CAAC,QAAQ,CAAC,IAAI,CAAC,CAAC,KAAK,EAAE,GAAG,IAAI,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,WAAW,GAAG,MAAM,CAAC;QAC1E,EAAE,CAAC,CAAC,IAAI,GAAG,CAAC,CAAC,CAAC,CAAC;YACX,IAAI,CAAC,CAAC,CAAC,GAAG,CAAC,EAAE,aAAa,EAAE,UAAU,EAAE,CAAC,CAAA;YACzC,IAAI,GAAG,MAAM,CAAA;YACb,KAAK,GAAG,MAAM,CAAA;QAClB,CAAC;QAED,gBAAgB;QAChB,EAAE,CAAC,CAAC,GAAG,GAAG,IAAI,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,YAAY,IAAI,CAAC,CAAC,QAAQ,CAAC,IAAI,CAAC,CAAC,MAAM,EAAE,CAAC,CAAC,CAAC;YAC5D,GAAG,GAAG,IAAI,CAAC,IAAI,CAAC,GAAG,GAAG,IAAI,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,YAAY,CAAA;QAChD,CAAC;QAED,IAAI,CAAC,CAAC,CAAC,GAAG,CAAC,EAAE,IAAI,EAAE,GAAG,EAAE,KAAK,EAAE,CAAC,CAAC;IACrC,CAAC;CACJ;AA3CD,kCA2CC"} \ No newline at end of file diff --git a/dist/main/atom/views/typeOverlayView.js b/dist/main/atom/views/typeOverlayView.js deleted file mode 100644 index 8fd6d6830..000000000 --- a/dist/main/atom/views/typeOverlayView.js +++ /dev/null @@ -1,13 +0,0 @@ -"use strict"; -var escapeHtml = require("escape-html"); -function create(type, comment) { - var overlayHTML = "\n " + escapeHtml(type) + "\n "; - if (comment) { - overlayHTML += "\n
    \n
    \n " + escapeHtml(comment).replace(/(?:\r\n|\r|\n)/g, '
    ') + "\n
    \n "; - } - var overlay = document.createElement('div'); - overlay.className = 'atomts-show-type-view'; - overlay.innerHTML = overlayHTML; - return overlay; -} -exports.create = create; diff --git a/dist/main/atom/views/view.js b/dist/main/atom/views/view.js index b712139cb..6bb3a0f6c 100644 --- a/dist/main/atom/views/view.js +++ b/dist/main/atom/views/view.js @@ -1,52 +1,35 @@ "use strict"; -var __extends = (this && this.__extends) || function (d, b) { - for (var p in b) if (b.hasOwnProperty(p)) d[p] = b[p]; - function __() { this.constructor = d; } - d.prototype = b === null ? Object.create(b) : (__.prototype = b.prototype, new __()); -}; -var sp = require("atom-space-pen-views"); -var View = (function (_super) { - __extends(View, _super); - function View(options) { - var _this = _super.call(this) || this; - _this.options = options; - _this.init(); - return _this; +Object.defineProperty(exports, "__esModule", { value: true }); +const sp = require("atom-space-pen-views"); +class View extends sp.View { + constructor(options) { + super(); + this.options = options; + this.init(); } - Object.defineProperty(View.prototype, "$", { - get: function () { - return this; - }, - enumerable: true, - configurable: true - }); - View.content = function () { + get $() { + return this; + } + static content() { throw new Error('Must override the base View static content member'); - }; - View.prototype.init = function () { }; - return View; -}(sp.View)); + } + init() { } +} exports.View = View; exports.$ = sp.$; -var ScrollView = (function (_super) { - __extends(ScrollView, _super); - function ScrollView(options) { - var _this = _super.call(this) || this; - _this.options = options; - _this.init(); - return _this; +class ScrollView extends sp.ScrollView { + constructor(options) { + super(); + this.options = options; + this.init(); } - Object.defineProperty(ScrollView.prototype, "$", { - get: function () { - return this; - }, - enumerable: true, - configurable: true - }); - ScrollView.content = function () { + get $() { + return this; + } + static content() { throw new Error('Must override the base View static content member'); - }; - ScrollView.prototype.init = function () { }; - return ScrollView; -}(sp.ScrollView)); + } + init() { } +} exports.ScrollView = ScrollView; +//# sourceMappingURL=view.js.map \ No newline at end of file diff --git a/dist/main/atom/views/view.js.map b/dist/main/atom/views/view.js.map new file mode 100644 index 000000000..35eb04e92 --- /dev/null +++ b/dist/main/atom/views/view.js.map @@ -0,0 +1 @@ +{"version":3,"file":"view.js","sourceRoot":"","sources":["../../../../lib/main/atom/views/view.ts"],"names":[],"mappings":";;AAAA,2CAA4C;AAE5C,UAA2B,SAAQ,EAAE,CAAC,IAAI;IAStC,YAAmB,OAAgB;QAC/B,KAAK,EAAE,CAAC;QADO,YAAO,GAAP,OAAO,CAAS;QAE/B,IAAI,CAAC,IAAI,EAAE,CAAC;IAChB,CAAC;IAXD,IAAI,CAAC;QACD,MAAM,CAAM,IAAI,CAAC;IACrB,CAAC;IAED,MAAM,CAAC,OAAO;QACV,MAAM,IAAI,KAAK,CAAC,mDAAmD,CAAC,CAAC;IACzE,CAAC;IAMD,IAAI,KAAK,CAAC;CACb;AAdD,oBAcC;AAEU,QAAA,CAAC,GAAG,EAAE,CAAC,CAAC,CAAC;AAEpB,gBAAiC,SAAQ,EAAE,CAAC,UAAU;IASlD,YAAmB,OAAgB;QAC/B,KAAK,EAAE,CAAC;QADO,YAAO,GAAP,OAAO,CAAS;QAE/B,IAAI,CAAC,IAAI,EAAE,CAAC;IAChB,CAAC;IAXD,IAAI,CAAC;QACD,MAAM,CAAM,IAAI,CAAC;IACrB,CAAC;IAED,MAAM,CAAC,OAAO;QACV,MAAM,IAAI,KAAK,CAAC,mDAAmD,CAAC,CAAC;IACzE,CAAC;IAMD,IAAI,KAAK,CAAC;CACb;AAdD,gCAcC"} \ No newline at end of file diff --git a/dist/main/atomts.js b/dist/main/atomts.js index 99faca211..d5a5c7e53 100644 --- a/dist/main/atomts.js +++ b/dist/main/atomts.js @@ -1,203 +1,187 @@ "use strict"; -var atomConfig = require("./atom/atomConfig"); -var makeTypeScriptGlobal_1 = require("../typescript/makeTypeScriptGlobal"); -makeTypeScriptGlobal_1.makeTsGlobal(atomConfig.typescriptServices); -var path = require("path"); -var fs = require("fs"); -var mainPanelView_1 = require("./atom/views/mainPanelView"); -var autoCompleteProvider = require("./atom/autoCompleteProvider"); -var tooltipManager = require("./atom/tooltipManager"); -var atomUtils = require("./atom/atomUtils"); -var commands = require("./atom/commands/commands"); -var onSaveHandler = require("./atom/onSaveHandler"); -var debugAtomTs = require("./atom/debugAtomTs"); -var atom_space_pen_views_1 = require("atom-space-pen-views"); -var documentationView = require("./atom/views/documentationView"); -var renameView = require("./atom/views/renameView"); -var mainPanelView = require("./atom/views/mainPanelView"); -var semanticView = require("./atom/views/semanticView"); -var fileStatusCache_1 = require("./atom/fileStatusCache"); -var editorSetup = require("./atom/editorSetup"); -var statusBar; -var statusBarMessage; -var editorWatch; -var autoCompleteWatch; -var parent = require("../worker/parent"); -exports.config = atomConfig.schema; -var utils_1 = require("./lang/utils"); -var hideIfNotActiveOnStart = utils_1.debounce(function () { - var editor = atom.workspace.getActiveTextEditor(); - if (!atomUtils.onDiskAndTsRelated(editor)) { - mainPanelView.hide(); - } -}, 100); -var __onlyOnce = false; -function onlyOnceStuff() { - if (__onlyOnce) - return; - else - __onlyOnce = true; - mainPanelView.attach(); - documentationView.attach(); - renameView.attach(); - semanticView.attach(); -} -function readyToActivate() { - parent.startWorker(); - atom.workspace.onDidChangeActivePaneItem(function (editor) { - if (atomUtils.onDiskAndTs(editor)) { - var filePath = editor.getPath(); - onlyOnceStuff(); - parent.getProjectFileDetails({ filePath: filePath }).then(function (res) { - mainPanelView.panelView.setTsconfigInUse(res.projectFilePath); - }).catch(function (err) { - mainPanelView.panelView.setTsconfigInUse(''); - }); - parent.errorsForFile({ filePath: filePath }) - .then(function (resp) { - mainPanelView_1.errorView.setErrors(filePath, resp.errors); - atomUtils.triggerLinter(); - }); - mainPanelView.panelView.updateFileStatus(filePath); - mainPanelView.show(); - } - else if (atomUtils.onDiskAndTsRelated(editor)) { - mainPanelView.show(); +Object.defineProperty(exports, "__esModule", { value: true }); +const tslib_1 = require("tslib"); +const Atom = require("atom"); +const tsconfig = require("tsconfig/dist/tsconfig"); +const renameView_1 = require("./atom/views/renameView"); +const autoCompleteProvider_1 = require("./atom/autoCompleteProvider"); +const clientResolver_1 = require("../client/clientResolver"); +const atom_1 = require("atom"); +const lodash_1 = require("lodash"); +const errorPusher_1 = require("./errorPusher"); +const lodash_2 = require("lodash"); +const statusPanel_1 = require("./atom/components/statusPanel"); +const typescriptEditorPane_1 = require("./typescriptEditorPane"); +const typescriptBuffer_1 = require("./typescriptBuffer"); +// globals +const subscriptions = new atom_1.CompositeDisposable(); +exports.clientResolver = new clientResolver_1.ClientResolver(); +const panes = []; +// Register all custom components +require("./atom/components"); +const commands_1 = require("./atom/commands"); +let linter; +let statusBar; +function activate(state) { + require('atom-package-deps').install('atom-typescript', true).then(() => { + let statusPriority = 100; + for (const panel of statusBar.getRightTiles()) { + if (panel.getItem().tagName === "GRAMMAR-SELECTOR-STATUS") { + statusPriority = panel.getPriority() - 1; + } } - else { - mainPanelView.hide(); + // Add the rename view + const { renameView } = renameView_1.attach(); + const statusPanel = statusPanel_1.StatusPanel.create(); + statusBar.addRightTile({ + item: statusPanel, + priority: statusPriority + }); + subscriptions.add(statusPanel); + const errorPusher = new errorPusher_1.ErrorPusher(); + errorPusher.setUnusedAsInfo(atom.config.get("atom-typescript.unusedAsInfo")); + subscriptions.add(atom.config.onDidChange("atom-typescript.unusedAsInfo", (val) => { + errorPusher.setUnusedAsInfo(val.newValue); + })); + exports.clientResolver.on("pendingRequestsChange", () => { + const pending = lodash_2.flatten(lodash_2.values(exports.clientResolver.clients).map(cl => cl.pending)); + statusPanel.setPending(pending); + }); + if (linter) { + errorPusher.setLinter(linter); + exports.clientResolver.on("diagnostics", ({ type, filePath, diagnostics }) => { + errorPusher.setErrors(type, filePath, diagnostics); + }); } - }); - editorWatch = atom.workspace.observeTextEditors(function (editor) { - var editorView = atom_space_pen_views_1.$(atom.views.getView(editor)); - tooltipManager.attach(editorView, editor); - var filePath = editor.getPath(); - var ext = path.extname(filePath); - if (atomUtils.isAllowedExtension(ext)) { - var isTst = ext === '.tst'; - try { - onlyOnceStuff(); - parent.getProjectFileDetails({ filePath: filePath }).then(function (res) { - mainPanelView.panelView.setTsconfigInUse(res.projectFilePath); - }).catch(function (err) { - mainPanelView.panelView.setTsconfigInUse(''); - }); - var onDisk = false; - if (fs.existsSync(filePath)) { - onDisk = true; - } - hideIfNotActiveOnStart(); - debugAtomTs.runDebugCode({ filePath: filePath, editor: editor }); - if (onDisk) { - parent.updateText({ filePath: filePath, text: editor.getText() }) - .then(function () { return parent.errorsForFile({ filePath: filePath }); }) - .then(function (resp) { return mainPanelView_1.errorView.setErrors(filePath, resp.errors); }); - parent.getOutputJsStatus({ filePath: filePath }).then(function (res) { - var status = fileStatusCache_1.getFileStatus(filePath); - status.emitDiffers = res.emitDiffers; - var ed = atom.workspace.getActiveTextEditor(); - if (ed && ed.getPath() === filePath) { - mainPanelView.panelView.updateFileStatus(filePath); - } - }); - } - editorSetup.setupEditor(editor); - var changeObserver = editor.onDidStopChanging(function () { - if (editor === atom.workspace.getActiveTextEditor()) { - var status_1 = fileStatusCache_1.getFileStatus(filePath); - status_1.modified = editor.isModified(); - mainPanelView.panelView.updateFileStatus(filePath); - } - if (!onDisk) { - var root = { line: 0, col: 0 }; - mainPanelView_1.errorView.setErrors(filePath, [{ startPos: root, endPos: root, filePath: filePath, message: "Please save file for it be processed by TypeScript", preview: "" }]); - return; + // Register the commands + commands_1.registerCommands({ + clearErrors() { + errorPusher.clear(); + }, + getTypescriptBuffer, + getClient(filePath) { + return tslib_1.__awaiter(this, void 0, void 0, function* () { + const pane = panes.find(pane => pane.filePath === filePath); + if (pane) { + return pane.client; } - parent.errorsForFile({ filePath: filePath }) - .then(function (resp) { return mainPanelView_1.errorView.setErrors(filePath, resp.errors); }); - }); - var buffer = editor.buffer; - var fasterChangeObserver = editor.buffer.onDidChange(function (diff) { - var newText = diff.newText; - var oldText = diff.oldText; - var start = { line: diff.oldRange.start.row, col: diff.oldRange.start.column }; - var end = { line: diff.oldRange.end.row, col: diff.oldRange.end.column }; - var promise = parent.editText({ filePath: filePath, start: start, end: end, newText: newText }); - }); - var saveObserver = editor.onDidSave(function (event) { - onDisk = true; - filePath = event.path; - onSaveHandler.handle({ filePath: filePath, editor: editor }); - }); - var destroyObserver = editor.onDidDestroy(function () { - mainPanelView_1.errorView.setErrors(filePath, []); - changeObserver.dispose(); - fasterChangeObserver.dispose(); - saveObserver.dispose(); - destroyObserver.dispose(); + return exports.clientResolver.get(filePath); }); + }, + renameView, + statusPanel, + }); + let activePane; + const onSave = lodash_1.debounce((pane) => { + if (!pane.client) + return; + const files = panes + .sort((a, b) => a.activeAt - b.activeAt) + .filter(_pane => _pane.filePath && _pane.isTypescript && _pane.client === pane.client) + .map(pane => pane.filePath); + pane.client.executeGetErr({ files, delay: 100 }); + }, 50); + subscriptions.add(atom.workspace.observeTextEditors((editor) => { + panes.push(new typescriptEditorPane_1.TypescriptEditorPane(editor, { + getClient: (filePath) => exports.clientResolver.get(filePath), + onDispose(pane) { + if (activePane === pane) { + activePane = undefined; + } + panes.splice(panes.indexOf(pane), 1); + // Clear errors if any from this pane + errorPusher.setErrors("syntaxDiag", pane.filePath, []); + errorPusher.setErrors("semanticDiag", pane.filePath, []); + }, + onSave, + statusPanel, + })); + })); + activePane = panes.find(pane => pane.editor === atom.workspace.getActiveTextEditor()); + if (activePane) { + activePane.onActivated(); + } + subscriptions.add(atom.workspace.onDidChangeActivePaneItem((editor) => { + if (activePane) { + activePane.onDeactivated(); + activePane = undefined; } - catch (ex) { - console.error('Solve this in atom-typescript', ex); - throw ex; + if (atom.workspace.isTextEditor(editor)) { + const pane = panes.find(pane => pane.editor === editor); + if (pane) { + activePane = pane; + pane.onActivated(); + } } - } + })); }); - commands.registerCommands(); -} -function activate(state) { - require('atom-package-deps').install('atom-typescript').then(waitForGrammarActivation).then(readyToActivate); } exports.activate = activate; function deactivate() { - if (statusBarMessage) - statusBarMessage.destroy(); - if (editorWatch) - editorWatch.dispose(); - if (autoCompleteWatch) - autoCompleteWatch.dispose(); - parent.stopWorker(); + subscriptions.dispose(); } exports.deactivate = deactivate; function serialize() { return {}; } exports.serialize = serialize; -function deserialize() { +function consumeLinter(registry) { + linter = registry.register({ + name: "Typescript" + }); +} +exports.consumeLinter = consumeLinter; +function consumeStatusBar(_statusBar) { + statusBar = _statusBar; } -exports.deserialize = deserialize; +exports.consumeStatusBar = consumeStatusBar; +// Registering an autocomplete provider function provide() { - return [autoCompleteProvider.provider]; + return [ + new autoCompleteProvider_1.AutocompleteProvider(exports.clientResolver, { getTypescriptBuffer }), + ]; } exports.provide = provide; -var linter = require("../linter"); -function provideLinter() { - return linter.provider; -} -exports.provideLinter = provideLinter; -function consumeSnippets(snippetsManager) { - atomUtils._setSnippetsManager(snippetsManager); +exports.config = { + unusedAsInfo: { + title: 'Show unused values with severity info', + description: 'Show unused values with severity \'info\' instead of \'error\'', + type: 'boolean', + default: true + } +}; +function loadProjectConfig(sourcePath) { + return exports.clientResolver.get(sourcePath).then(client => { + return client.executeProjectInfo({ needFileNameList: false, file: sourcePath }).then(result => { + return tsconfig.load(result.body.configFileName); + }); + }); } -exports.consumeSnippets = consumeSnippets; -function waitForGrammarActivation() { - var activated = false; - var promise = new Promise(function (resolve, reject) { - var editorWatch = atom.workspace.observeTextEditors(function (editor) { - if (activated) - return; - editor.observeGrammar(function (grammar) { - if (grammar.packageName === 'atom-typescript') { - activated = true; - resolve({}); - editorWatch.dispose(); - } +exports.loadProjectConfig = loadProjectConfig; +// Get Typescript buffer for the given path +function getTypescriptBuffer(filePath) { + return tslib_1.__awaiter(this, void 0, void 0, function* () { + const pane = panes.find(pane => pane.filePath === filePath); + if (pane) { + return { + buffer: pane.buffer, + isOpen: true + }; + } + // Wait for the buffer to load before resolving the promise + const buffer = yield new Promise(resolve => { + const buffer = new Atom.TextBuffer({ + filePath, + load: true + }); + buffer.onDidReload(() => { + resolve(buffer); }); }); + return { + buffer: new typescriptBuffer_1.TypescriptBuffer(buffer, filePath => exports.clientResolver.get(filePath)), + isOpen: false + }; }); - return promise; -} -var hyperclickProvider = require("../hyperclickProvider"); -function getHyperclickProvider() { - return hyperclickProvider; } -exports.getHyperclickProvider = getHyperclickProvider; +//# sourceMappingURL=atomts.js.map \ No newline at end of file diff --git a/dist/main/atomts.js.map b/dist/main/atomts.js.map new file mode 100644 index 000000000..c2fee2bba --- /dev/null +++ b/dist/main/atomts.js.map @@ -0,0 +1 @@ +{"version":3,"file":"atomts.js","sourceRoot":"","sources":["../../lib/main/atomts.ts"],"names":[],"mappings":";;;AAAA,6BAA4B;AAC5B,mDAAkD;AAClD,wDAAkE;AAClE,sEAAgE;AAChE,6DAAuD;AACvD,+BAAwC;AACxC,mCAA+B;AAC/B,+CAAyC;AACzC,mCAAsC;AAGtC,+DAAyD;AACzD,iEAA2D;AAC3D,yDAAmD;AAEnD,UAAU;AACV,MAAM,aAAa,GAAG,IAAI,0BAAmB,EAAE,CAAA;AAClC,QAAA,cAAc,GAAG,IAAI,+BAAc,EAAE,CAAA;AAClD,MAAM,KAAK,GAA2B,EAAE,CAAA;AAExC,iCAAiC;AACjC,6BAA0B;AAC1B,8CAAgD;AAEhD,IAAI,MAAc,CAAA;AAClB,IAAI,SAAoB,CAAA;AAIxB,kBAAyB,KAAmB;IAC1C,OAAO,CAAC,mBAAmB,CAAC,CAAC,OAAO,CAAC,iBAAiB,EAAE,IAAI,CAAC,CAAC,IAAI,CAAC;QAEjE,IAAI,cAAc,GAAG,GAAG,CAAA;QACxB,GAAG,CAAC,CAAC,MAAM,KAAK,IAAI,SAAS,CAAC,aAAa,EAAE,CAAC,CAAC,CAAC;YAC9C,EAAE,CAAC,CAAC,KAAK,CAAC,OAAO,EAAE,CAAC,OAAO,KAAK,yBAAyB,CAAC,CAAC,CAAC;gBAC1D,cAAc,GAAG,KAAK,CAAC,WAAW,EAAE,GAAG,CAAC,CAAA;YAC1C,CAAC;QACH,CAAC;QAED,sBAAsB;QACtB,MAAM,EAAC,UAAU,EAAC,GAAG,mBAAgB,EAAE,CAAA;QACvC,MAAM,WAAW,GAAG,yBAAW,CAAC,MAAM,EAAE,CAAA;QAExC,SAAS,CAAC,YAAY,CAAC;YACrB,IAAI,EAAE,WAAW;YACjB,QAAQ,EAAE,cAAc;SACzB,CAAC,CAAA;QAEF,aAAa,CAAC,GAAG,CAAC,WAAW,CAAC,CAAA;QAC9B,MAAM,WAAW,GAAG,IAAI,yBAAW,EAAE,CAAA;QACrC,WAAW,CAAC,eAAe,CAAC,IAAI,CAAC,MAAM,CAAC,GAAG,CAAC,8BAA8B,CAAC,CAAC,CAAA;QAC5E,aAAa,CAAC,GAAG,CAAC,IAAI,CAAC,MAAM,CAAC,WAAW,CAAC,8BAA8B,EACtE,CAAC,GAA2C;YAC1C,WAAW,CAAC,eAAe,CAAC,GAAG,CAAC,QAAQ,CAAC,CAAA;QAC3C,CAAC,CACF,CAAC,CAAA;QAEF,sBAAc,CAAC,EAAE,CAAC,uBAAuB,EAAE;YACzC,MAAM,OAAO,GAAG,gBAAO,CAAC,eAAM,CAAC,sBAAc,CAAC,OAAO,CAAC,CAAC,GAAG,CAAC,EAAE,IAAI,EAAE,CAAC,OAAO,CAAC,CAAC,CAAA;YAC7E,WAAW,CAAC,UAAU,CAAC,OAAO,CAAC,CAAA;QACjC,CAAC,CAAC,CAAA;QAEF,EAAE,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC;YACX,WAAW,CAAC,SAAS,CAAC,MAAM,CAAC,CAAA;YAE7B,sBAAc,CAAC,EAAE,CAAC,aAAa,EAAE,CAAC,EAAC,IAAI,EAAE,QAAQ,EAAE,WAAW,EAAC;gBAC7D,WAAW,CAAC,SAAS,CAAC,IAAI,EAAE,QAAQ,EAAE,WAAW,CAAC,CAAA;YACpD,CAAC,CAAC,CAAA;QACJ,CAAC;QAED,wBAAwB;QACxB,2BAAgB,CAAC;YACf,WAAW;gBACT,WAAW,CAAC,KAAK,EAAE,CAAA;YACrB,CAAC;YACD,mBAAmB;YACb,SAAS,CAAC,QAAgB;;oBAC9B,MAAM,IAAI,GAAG,KAAK,CAAC,IAAI,CAAC,IAAI,IAAI,IAAI,CAAC,QAAQ,KAAK,QAAQ,CAAC,CAAA;oBAC3D,EAAE,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC;wBACT,MAAM,CAAC,IAAI,CAAC,MAAM,CAAA;oBACpB,CAAC;oBAED,MAAM,CAAC,sBAAc,CAAC,GAAG,CAAC,QAAQ,CAAC,CAAA;gBACrC,CAAC;aAAA;YACD,UAAU;YACV,WAAW;SACZ,CAAC,CAAA;QAEF,IAAI,UAA4C,CAAA;QAEhD,MAAM,MAAM,GAAG,iBAAQ,CAAC,CAAC,IAA0B;YACjD,EAAE,CAAC,CAAC,CAAC,IAAI,CAAC,MAAM,CAAC;gBACf,MAAM,CAAA;YAER,MAAM,KAAK,GAAG,KAAK;iBAChB,IAAI,CAAC,CAAC,CAAC,EAAE,CAAC,KAAK,CAAC,CAAC,QAAQ,GAAG,CAAC,CAAC,QAAQ,CAAC;iBACvC,MAAM,CAAC,KAAK,IAAI,KAAK,CAAC,QAAQ,IAAI,KAAK,CAAC,YAAY,IAAI,KAAK,CAAC,MAAM,KAAK,IAAI,CAAC,MAAM,CAAC;iBACrF,GAAG,CAAC,IAAI,IAAI,IAAI,CAAC,QAAQ,CAAC,CAAA;YAE7B,IAAI,CAAC,MAAM,CAAC,aAAa,CAAC,EAAC,KAAK,EAAE,KAAK,EAAE,GAAG,EAAC,CAAC,CAAA;QAEhD,CAAC,EAAE,EAAE,CAAC,CAAA;QAEN,aAAa,CAAC,GAAG,CAAC,IAAI,CAAC,SAAS,CAAC,kBAAkB,CAAC,CAAC,MAAwB;YAC3E,KAAK,CAAC,IAAI,CAAC,IAAI,2CAAoB,CAAC,MAAM,EAAE;gBAC1C,SAAS,EAAE,CAAC,QAAgB,KAAK,sBAAc,CAAC,GAAG,CAAC,QAAQ,CAAC;gBAC7D,SAAS,CAAC,IAAI;oBACZ,EAAE,CAAC,CAAC,UAAU,KAAK,IAAI,CAAC,CAAC,CAAC;wBACxB,UAAU,GAAG,SAAS,CAAA;oBACxB,CAAC;oBAED,KAAK,CAAC,MAAM,CAAC,KAAK,CAAC,OAAO,CAAC,IAAI,CAAC,EAAE,CAAC,CAAC,CAAA;oBAEpC,qCAAqC;oBACrC,WAAW,CAAC,SAAS,CAAC,YAAY,EAAE,IAAI,CAAC,QAAQ,EAAE,EAAE,CAAC,CAAA;oBACtD,WAAW,CAAC,SAAS,CAAC,cAAc,EAAE,IAAI,CAAC,QAAQ,EAAE,EAAE,CAAC,CAAA;gBAC1D,CAAC;gBACD,MAAM;gBACN,WAAW;aACZ,CAAC,CAAC,CAAA;QACL,CAAC,CAAC,CAAC,CAAA;QAEH,UAAU,GAAG,KAAK,CAAC,IAAI,CAAC,IAAI,IAAI,IAAI,CAAC,MAAM,KAAK,IAAI,CAAC,SAAS,CAAC,mBAAmB,EAAE,CAAC,CAAA;QAErF,EAAE,CAAC,CAAC,UAAU,CAAC,CAAC,CAAC;YACf,UAAU,CAAC,WAAW,EAAE,CAAA;QAC1B,CAAC;QAED,aAAa,CAAC,GAAG,CAAC,IAAI,CAAC,SAAS,CAAC,yBAAyB,CAAC,CAAC,MAAwB;YAClF,EAAE,CAAC,CAAC,UAAU,CAAC,CAAC,CAAC;gBACf,UAAU,CAAC,aAAa,EAAE,CAAA;gBAC1B,UAAU,GAAG,SAAS,CAAA;YACxB,CAAC;YAED,EAAE,CAAC,CAAC,IAAI,CAAC,SAAS,CAAC,YAAY,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC;gBACxC,MAAM,IAAI,GAAG,KAAK,CAAC,IAAI,CAAC,IAAI,IAAI,IAAI,CAAC,MAAM,KAAK,MAAM,CAAC,CAAA;gBACvD,EAAE,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC;oBACT,UAAU,GAAG,IAAI,CAAA;oBACjB,IAAI,CAAC,WAAW,EAAE,CAAA;gBACpB,CAAC;YACH,CAAC;QACH,CAAC,CAAC,CAAC,CAAA;IACL,CAAC,CAAC,CAAA;AACJ,CAAC;AAlHD,4BAkHC;AAED;IACE,aAAa,CAAC,OAAO,EAAE,CAAA;AACzB,CAAC;AAFD,gCAEC;AAED;IACE,MAAM,CAAC,EAAE,CAAA;AACX,CAAC;AAFD,8BAEC;AAED,uBAA8B,QAAwB;IACpD,MAAM,GAAG,QAAQ,CAAC,QAAQ,CAAC;QACzB,IAAI,EAAE,YAAY;KACnB,CAAC,CAAA;AACJ,CAAC;AAJD,sCAIC;AAED,0BAAiC,UAAqB;IACpD,SAAS,GAAG,UAAU,CAAA;AACxB,CAAC;AAFD,4CAEC;AAED,uCAAuC;AACvC;IACE,MAAM,CAAC;QACL,IAAI,2CAAoB,CAAC,sBAAc,EAAE,EAAC,mBAAmB,EAAC,CAAC;KAChE,CAAA;AACH,CAAC;AAJD,0BAIC;AAEU,QAAA,MAAM,GAAG;IAClB,YAAY,EAAE;QACZ,KAAK,EAAE,uCAAuC;QAC9C,WAAW,EAAE,gEAAgE;QAC7E,IAAI,EAAE,SAAS;QACf,OAAO,EAAE,IAAI;KACd;CACF,CAAA;AAED,2BAAkC,UAAkB;IAClD,MAAM,CAAC,sBAAc,CAAC,GAAG,CAAC,UAAU,CAAC,CAAC,IAAI,CAAC,MAAM;QAC/C,MAAM,CAAC,MAAM,CAAC,kBAAkB,CAAC,EAAC,gBAAgB,EAAE,KAAK,EAAE,IAAI,EAAE,UAAU,EAAC,CAAC,CAAC,IAAI,CAAC,MAAM;YACvF,MAAM,CAAC,QAAQ,CAAC,IAAI,CAAC,MAAM,CAAC,IAAK,CAAC,cAAc,CAAC,CAAA;QACnD,CAAC,CAAC,CAAA;IACJ,CAAC,CAAC,CAAA;AACJ,CAAC;AAND,8CAMC;AAED,2CAA2C;AAC3C,6BAAmC,QAAgB;;QACjD,MAAM,IAAI,GAAG,KAAK,CAAC,IAAI,CAAC,IAAI,IAAI,IAAI,CAAC,QAAQ,KAAK,QAAQ,CAAC,CAAA;QAC3D,EAAE,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC;YACT,MAAM,CAAC;gBACL,MAAM,EAAE,IAAI,CAAC,MAAM;gBACnB,MAAM,EAAE,IAAI;aACb,CAAA;QACH,CAAC;QAED,2DAA2D;QAC3D,MAAM,MAAM,GAAG,MAAM,IAAI,OAAO,CAAyB,OAAO;YAC9D,MAAM,MAAM,GAAG,IAAI,IAAI,CAAC,UAAU,CAAC;gBACjC,QAAQ;gBACR,IAAI,EAAE,IAAI;aACX,CAAC,CAAA;YAEF,MAAM,CAAC,WAAW,CAAC;gBACjB,OAAO,CAAC,MAAM,CAAC,CAAA;YACjB,CAAC,CAAC,CAAA;QACJ,CAAC,CAAC,CAAA;QAEF,MAAM,CAAC;YACL,MAAM,EAAE,IAAI,mCAAgB,CAAC,MAAM,EAAE,QAAQ,IAAI,sBAAc,CAAC,GAAG,CAAC,QAAQ,CAAC,CAAC;YAC9E,MAAM,EAAE,KAAK;SACd,CAAA;IACH,CAAC;CAAA"} \ No newline at end of file diff --git a/dist/main/bin/atbuild b/dist/main/bin/atbuild deleted file mode 100755 index a6a24d07a..000000000 --- a/dist/main/bin/atbuild +++ /dev/null @@ -1,2 +0,0 @@ -#! /usr/bin/env node -require('./atbuild.js'); diff --git a/dist/main/bin/atbuild.js b/dist/main/bin/atbuild.js deleted file mode 100644 index 689bd6e78..000000000 --- a/dist/main/bin/atbuild.js +++ /dev/null @@ -1,33 +0,0 @@ -"use strict"; -var makeTypeScriptGlobal_1 = require("../../typescript/makeTypeScriptGlobal"); -makeTypeScriptGlobal_1.makeTsGlobal(); -var tsconfig = require("../tsconfig/tsconfig"); -var building = require("../lang/modules/building"); -var project_1 = require("../lang/core/project"); -var utils_1 = require("../lang/utils"); -var startLoc; -if (process.argv.length > 2) { - startLoc = process.argv[2]; -} -else { - startLoc = process.cwd(); -} -var projectFile = tsconfig.getProjectSync(startLoc); -console.log("Compiling using project file: " + projectFile.projectFilePath); -var proj = new project_1.Project(projectFile); -var errors = utils_1.selectMany(proj.projectFile.project.files.map(function (filePath) { - var output = building.emitFile(proj, filePath); - return output.errors; -})); -building.emitDts(proj); -if (errors.length == 0) { - console.log('Compile successfull'); - process.exit(0); -} -else { - console.log('Errors:'); - errors.forEach(function (e) { - console.log(e.filePath, e.message); - }); - process.exit(1); -} diff --git a/dist/main/errorPusher.js b/dist/main/errorPusher.js new file mode 100644 index 000000000..0281f9a93 --- /dev/null +++ b/dist/main/errorPusher.js @@ -0,0 +1,59 @@ +"use strict"; +Object.defineProperty(exports, "__esModule", { value: true }); +const lodash_1 = require("lodash"); +const utils_1 = require("./atom/utils"); +/** Class that collects errors from all of the clients and pushes them to the Linter service */ +class ErrorPusher { + constructor() { + this.errors = new Map(); + this.unusedAsInfo = true; + this.pushErrors = lodash_1.debounce(() => { + const errors = []; + for (const fileErrors of this.errors.values()) { + for (const [filePath, diagnostics] of fileErrors) { + const _filePath = utils_1.systemPath(filePath); + for (const diagnostic of diagnostics) { + errors.push({ + type: this.unusedAsInfo && diagnostic.code === 6133 ? "Info" : "Error", + text: diagnostic.text, + filePath: _filePath, + range: diagnostic.start ? utils_1.locationsToRange(diagnostic.start, diagnostic.end) : undefined + }); + } + } + } + if (this.linter) { + this.linter.setMessages(errors); + } + }, 100); + } + /** Set errors. Previous errors with the same prefix and filePath are going to be replaced */ + setErrors(prefix, filePath, errors) { + if (prefix == undefined || filePath == undefined) { + console.warn("setErrors: prefix or filePath is undefined", prefix, filePath); + return; + } + let prefixed = this.errors.get(prefix); + if (!prefixed) { + prefixed = new Map(); + this.errors.set(prefix, prefixed); + } + prefixed.set(filePath, errors); + this.pushErrors(); + } + setUnusedAsInfo(unusedAsInfo) { + this.unusedAsInfo = unusedAsInfo; + } + /** Clear all errors */ + clear() { + if (this.linter) { + this.linter.deleteMessages(); + } + } + setLinter(linter) { + this.linter = linter; + this.pushErrors(); + } +} +exports.ErrorPusher = ErrorPusher; +//# sourceMappingURL=errorPusher.js.map \ No newline at end of file diff --git a/dist/main/errorPusher.js.map b/dist/main/errorPusher.js.map new file mode 100644 index 000000000..9f67f9d3d --- /dev/null +++ b/dist/main/errorPusher.js.map @@ -0,0 +1 @@ +{"version":3,"file":"errorPusher.js","sourceRoot":"","sources":["../../lib/main/errorPusher.ts"],"names":[],"mappings":";;AAAA,mCAA+B;AAG/B,wCAAyD;AAEzD,+FAA+F;AAC/F;IAAA;QAEU,WAAM,GAA2C,IAAI,GAAG,EAAE,CAAA;QAC1D,iBAAY,GAAG,IAAI,CAAA;QAoCnB,eAAU,GAAG,iBAAQ,CAAC;YAC5B,MAAM,MAAM,GAAoB,EAAE,CAAA;YAElC,GAAG,CAAC,CAAC,MAAM,UAAU,IAAI,IAAI,CAAC,MAAM,CAAC,MAAM,EAAE,CAAC,CAAC,CAAC;gBAC9C,GAAG,CAAC,CAAC,MAAM,CAAC,QAAQ,EAAE,WAAW,CAAC,IAAI,UAAU,CAAC,CAAC,CAAC;oBACjD,MAAM,SAAS,GAAG,kBAAU,CAAC,QAAQ,CAAC,CAAA;oBACtC,GAAG,CAAC,CAAC,MAAM,UAAU,IAAI,WAAW,CAAC,CAAC,CAAC;wBACrC,MAAM,CAAC,IAAI,CAAC;4BACV,IAAI,EAAE,IAAI,CAAC,YAAY,IAAI,UAAU,CAAC,IAAI,KAAK,IAAI,GAAG,MAAM,GAAG,OAAO;4BACtE,IAAI,EAAE,UAAU,CAAC,IAAI;4BACrB,QAAQ,EAAE,SAAS;4BACnB,KAAK,EAAE,UAAU,CAAC,KAAK,GAAG,wBAAgB,CAAC,UAAU,CAAC,KAAK,EAAE,UAAU,CAAC,GAAG,CAAC,GAAG,SAAS;yBACzF,CAAC,CAAA;oBACJ,CAAC;gBACH,CAAC;YACH,CAAC;YAED,EAAE,CAAC,CAAC,IAAI,CAAC,MAAM,CAAC,CAAC,CAAC;gBAChB,IAAI,CAAC,MAAM,CAAC,WAAW,CAAC,MAAM,CAAC,CAAA;YACjC,CAAC;QACH,CAAC,EAAE,GAAG,CAAC,CAAA;IACT,CAAC;IAvDC,6FAA6F;IAC7F,SAAS,CAAC,MAA0B,EAAE,QAA4B,EAAE,MAAoB;QACtF,EAAE,CAAC,CAAC,MAAM,IAAI,SAAS,IAAI,QAAQ,IAAI,SAAS,CAAC,CAAC,CAAC;YACjD,OAAO,CAAC,IAAI,CAAC,4CAA4C,EAAE,MAAM,EAAE,QAAQ,CAAC,CAAA;YAC5E,MAAM,CAAA;QACR,CAAC;QAED,IAAI,QAAQ,GAAG,IAAI,CAAC,MAAM,CAAC,GAAG,CAAC,MAAM,CAAC,CAAA;QACtC,EAAE,CAAC,CAAC,CAAC,QAAQ,CAAC,CAAC,CAAC;YACd,QAAQ,GAAG,IAAI,GAAG,EAAE,CAAA;YACpB,IAAI,CAAC,MAAM,CAAC,GAAG,CAAC,MAAM,EAAE,QAAQ,CAAC,CAAA;QACnC,CAAC;QAED,QAAQ,CAAC,GAAG,CAAC,QAAQ,EAAE,MAAM,CAAC,CAAA;QAE9B,IAAI,CAAC,UAAU,EAAE,CAAA;IACnB,CAAC;IAED,eAAe,CAAC,YAAqB;QACnC,IAAI,CAAC,YAAY,GAAG,YAAY,CAAA;IAClC,CAAC;IAED,uBAAuB;IACvB,KAAK;QACH,EAAE,CAAC,CAAC,IAAI,CAAC,MAAM,CAAC,CAAC,CAAC;YAChB,IAAI,CAAC,MAAM,CAAC,cAAc,EAAE,CAAA;QAC9B,CAAC;IACH,CAAC;IAED,SAAS,CAAC,MAAc;QACtB,IAAI,CAAC,MAAM,GAAG,MAAM,CAAA;QACpB,IAAI,CAAC,UAAU,EAAE,CAAA;IACnB,CAAC;CAuBF;AA5DD,kCA4DC"} \ No newline at end of file diff --git a/dist/main/json2dts/json2dts.js b/dist/main/json2dts/json2dts.js deleted file mode 100644 index 893efe6d7..000000000 --- a/dist/main/json2dts/json2dts.js +++ /dev/null @@ -1,22 +0,0 @@ -"use strict"; -var JSON2DTS = require("json2dts"); -var Json2dts = JSON2DTS.Json2dts; -var toValidJSON = JSON2DTS.toValidJSON; -function convert(content) { - try { - var converter = new Json2dts(); - var text2Obj = JSON.parse(toValidJSON(content)); - if (typeof text2Obj != "string") { - converter.parse(text2Obj, 'RootJson'); - content = converter.getCode(); - } - else { - atom.notifications.addError('Json2dts Invalid JSON'); - } - } - catch (e) { - atom.notifications.addError("Json2dts Invalid JSON error: " + e); - } - return content; -} -exports.convert = convert; diff --git a/dist/main/lang/core/languageServiceHost2.js b/dist/main/lang/core/languageServiceHost2.js deleted file mode 100644 index 7ea71023a..000000000 --- a/dist/main/lang/core/languageServiceHost2.js +++ /dev/null @@ -1,284 +0,0 @@ -"use strict"; -var path = require("path"); -var fs = require("fs"); -var os = require("os"); -var textBuffer = require("basarat-text-buffer"); -var typescriptServices_1 = require("../typescriptServices"); -function createScriptInfo(fileName, text, isOpen) { - if (isOpen === void 0) { isOpen = false; } - var version = 1; - var editRanges = []; - var _lineStarts; - var _lineStartIsDirty = true; - var buffer = new textBuffer(text); - function getLineStarts() { - if (_lineStartIsDirty) { - _lineStarts = []; - var totalLength = 0; - buffer.lines.forEach(function (line, index) { - _lineStarts.push(totalLength); - var lineLength = line.length; - totalLength = totalLength + lineLength + buffer.lineEndings[index].length; - }); - _lineStartIsDirty = false; - } - return _lineStarts; - } - function updateContent(newContent) { - buffer = new textBuffer(newContent); - _lineStartIsDirty = true; - editRanges = []; - version++; - } - function editContent(minChar, limChar, newText) { - var start = getLineAndColForPositon(minChar); - var end = getLineAndColForPositon(limChar); - buffer.setTextInRange([[start.line, start.col], [end.line, end.col]], newText, { normalizeLineEndings: false }); - _lineStartIsDirty = true; - editRanges.push({ - span: { start: minChar, length: limChar - minChar }, - newLength: newText.length - }); - version++; - } - function getPositionFromLine(line, ch) { - return buffer.characterIndexForPosition([line, ch]); - } - function getLineAndColForPositon(position) { - var _a = buffer.positionForCharacterIndex(position), row = _a.row, column = _a.column; - return { - line: row, - col: column - }; - } - function getLinePreview(line) { - return (buffer.lines[line] || '').trim(); - } - return { - getFileName: function () { return fileName; }, - getContent: function () { return buffer.getText(); }, - getVersion: function () { return version; }, - getIsOpen: function () { return isOpen; }, - setIsOpen: function (val) { return isOpen = val; }, - getEditRanges: function () { return editRanges; }, - getLineStarts: getLineStarts, - updateContent: updateContent, - editContent: editContent, - getPositionFromLine: getPositionFromLine, - getLineAndColForPositon: getLineAndColForPositon, - getLinePreview: getLinePreview - }; -} -function getScriptSnapShot(scriptInfo) { - var lineStarts = scriptInfo.getLineStarts(); - var textSnapshot = scriptInfo.getContent(); - var version = scriptInfo.getVersion(); - var editRanges = scriptInfo.getEditRanges(); - function getChangeRange(oldSnapshot) { - var unchanged = { span: { start: 0, length: 0 }, newLength: 0 }; - function collapseChangesAcrossMultipleVersions(changes) { - if (changes.length === 0) { - return unchanged; - } - if (changes.length === 1) { - return changes[0]; - } - var change0 = changes[0]; - var oldStartN = change0.span.start; - var oldEndN = change0.span.start + change0.span.length; - var newEndN = oldStartN + change0.newLength; - for (var i = 1; i < changes.length; i++) { - var nextChange = changes[i]; - var oldStart1 = oldStartN; - var oldEnd1 = oldEndN; - var newEnd1 = newEndN; - var oldStart2 = nextChange.span.start; - var oldEnd2 = nextChange.span.start + nextChange.span.length; - var newEnd2 = oldStart2 + nextChange.newLength; - oldStartN = Math.min(oldStart1, oldStart2); - oldEndN = Math.max(oldEnd1, oldEnd1 + (oldEnd2 - newEnd1)); - newEndN = Math.max(newEnd2, newEnd2 + (newEnd1 - oldEnd2)); - } - return { span: { start: oldStartN, length: oldEndN - oldStartN }, newLength: newEndN - oldStartN }; - } - ; - var scriptVersion = oldSnapshot.version || 0; - if (scriptVersion === version) { - return unchanged; - } - var initialEditRangeIndex = editRanges.length - (version - scriptVersion); - if (initialEditRangeIndex < 0) { - return null; - } - var entries = editRanges.slice(initialEditRangeIndex); - return collapseChangesAcrossMultipleVersions(entries); - } - return { - getText: function (start, end) { return textSnapshot.substring(start, end); }, - getLength: function () { return textSnapshot.length; }, - getChangeRange: getChangeRange, - }; -} -function getTypescriptLocation() { - if (typescriptServices_1.typescriptServices) { - return path.dirname(typescriptServices_1.typescriptServices); - } - else { - return path.dirname(require.resolve('typescript')); - } -} -exports.getDefaultLibFilePath = function (options) { - var filename = ts.getDefaultLibFileName(options); - return (path.join(getTypescriptLocation(), filename)).split('\\').join('/'); -}; -exports.typescriptDirectory = getTypescriptLocation().split('\\').join('/'); -var LanguageServiceHost = (function () { - function LanguageServiceHost(config) { - var _this = this; - this.config = config; - this.fileNameToScript = Object.create(null); - this.addScript = function (fileName, content) { - try { - if (!content) { - content = fs.readFileSync(fileName).toString(); - } - } - catch (ex) { - content = ''; - } - var script = createScriptInfo(fileName, content); - _this.fileNameToScript[fileName] = script; - }; - this.removeScript = function (fileName) { - delete _this.fileNameToScript[fileName]; - }; - this.removeAll = function () { - _this.fileNameToScript = Object.create(null); - }; - this.updateScript = function (fileName, content) { - var script = _this.fileNameToScript[fileName]; - if (script) { - script.updateContent(content); - return; - } - else { - _this.addScript(fileName, content); - } - }; - this.editScript = function (fileName, start, end, newText) { - var script = _this.fileNameToScript[fileName]; - if (script) { - var minChar = script.getPositionFromLine(start.line, start.col); - var limChar = script.getPositionFromLine(end.line, end.col); - script.editContent(minChar, limChar, newText); - return; - } - throw new Error('No script with name \'' + fileName + '\''); - }; - this.setScriptIsOpen = function (fileName, isOpen) { - var script = _this.fileNameToScript[fileName]; - if (script) { - script.setIsOpen(isOpen); - return; - } - throw new Error('No script with name \'' + fileName + '\''); - }; - this.getScriptContent = function (fileName) { - var script = _this.fileNameToScript[fileName]; - if (script) { - return script.getContent(); - } - return null; - }; - this.hasScript = function (fileName) { - return !!_this.fileNameToScript[fileName]; - }; - this.getIndexFromPosition = function (fileName, position) { - var script = _this.fileNameToScript[fileName]; - if (script) { - return script.getPositionFromLine(position.line, position.col); - } - return -1; - }; - this.getPositionFromIndex = function (fileName, index) { - if (!_this.fileNameToScript[fileName]) - _this.addScript(fileName); - var script = _this.fileNameToScript[fileName]; - if (script) { - return script.getLineAndColForPositon(index); - } - return null; - }; - this.getPositionFromTextSpanWithLinePreview = function (fileName, textSpan) { - var position = _this.getPositionFromIndex(fileName, textSpan.start); - var script = _this.fileNameToScript[fileName]; - var preview = script.getLinePreview(position.line); - return { preview: preview, position: position }; - }; - this.getCompilationSettings = function () { return _this.config.project.compilerOptions; }; - this.getNewLine = function () { - var eol = os.EOL; - switch (_this.config.project.compilerOptions.newLine) { - case ts.NewLineKind.CarriageReturnLineFeed: - eol = "\r\n"; - break; - case ts.NewLineKind.LineFeed: - eol = "\n"; - break; - } - return eol; - }; - this.getScriptFileNames = function () { return Object.keys(_this.fileNameToScript); }; - this.getScriptVersion = function (fileName) { - var script = _this.fileNameToScript[fileName]; - if (script) { - return '' + script.getVersion(); - } - return '0'; - }; - this.getScriptIsOpen = function (fileName) { - var script = _this.fileNameToScript[fileName]; - if (script) { - return script.getIsOpen(); - } - return false; - }; - this.getScriptSnapshot = function (fileName) { - var script = _this.fileNameToScript[fileName]; - if (script) { - return getScriptSnapShot(script); - } - else if (_this.fileExists(fileName)) { - _this.config.project.files.push(fileName); - _this.addScript(fileName); - return _this.getScriptSnapshot(fileName); - } - return null; - }; - this.getCurrentDirectory = function () { - return _this.config.projectFileDirectory; - }; - this.getDefaultLibFileName = ts.getDefaultLibFileName; - this.fileExists = function (path) { - try { - var stat = fs.statSync(path); - return stat.isFile(); - } - catch (error) { - return false; - } - }; - if (!config.project.compilerOptions.noLib && !config.project.compilerOptions.lib) { - this.addScript(exports.getDefaultLibFilePath(config.project.compilerOptions)); - } - else if (Array.isArray(config.project.compilerOptions.lib)) { - for (var _i = 0, _a = config.project.compilerOptions.lib; _i < _a.length; _i++) { - var lib = _a[_i]; - var filename = "lib." + lib + ".d.ts"; - this.addScript((path.join(getTypescriptLocation(), filename)).split('\\').join('/')); - } - } - } - return LanguageServiceHost; -}()); -exports.LanguageServiceHost = LanguageServiceHost; diff --git a/dist/main/lang/core/project.js b/dist/main/lang/core/project.js deleted file mode 100644 index 84c8150af..000000000 --- a/dist/main/lang/core/project.js +++ /dev/null @@ -1,38 +0,0 @@ -"use strict"; -var fs = require("fs"); -exports.languageServiceHost = require("./languageServiceHost2"); -var tsconfig = require("../../tsconfig/tsconfig"); -var transformerRegistry = require("../transformers/transformerRegistry"); -var Project = (function () { - function Project(projectFile) { - var _this = this; - this.projectFile = projectFile; - this.languageServiceHost = new exports.languageServiceHost.LanguageServiceHost(projectFile); - var transformerRegexes = transformerRegistry.getRegexes(); - projectFile.project.files.forEach(function (file) { - if (tsconfig.endsWith(file, '.tst.ts')) { - var rawContent = fs.readFileSync(tsconfig.removeExt(file), 'utf-8'); - var withoutTransform = rawContent; - transformerRegexes.forEach(function (transformer) { - withoutTransform = withoutTransform.replace(transformer, ''); - ; - }); - _this.languageServiceHost.addScript(file, withoutTransform); - } - else { - _this.languageServiceHost.addScript(file); - } - }); - this.languageService = ts.createLanguageService(this.languageServiceHost, ts.createDocumentRegistry()); - } - Project.prototype.getProjectSourceFiles = function () { - var libFile = exports.languageServiceHost.getDefaultLibFilePath(this.projectFile.project.compilerOptions); - var files = this.languageService.getProgram().getSourceFiles().filter(function (x) { return x.fileName !== libFile; }); - return files; - }; - Project.prototype.includesSourceFile = function (fileName) { - return (this.getProjectSourceFiles().filter(function (f) { return f.fileName === fileName; }).length === 1); - }; - return Project; -}()); -exports.Project = Project; diff --git a/dist/main/lang/fixmyts/astUtils.js b/dist/main/lang/fixmyts/astUtils.js deleted file mode 100644 index 26f82a79d..000000000 --- a/dist/main/lang/fixmyts/astUtils.js +++ /dev/null @@ -1,95 +0,0 @@ -"use strict"; -exports.forEachChild = ts.forEachChild; -function forEachChildRecursive(node, cbNode, depth) { - if (depth === void 0) { depth = 0; } - var res = cbNode(node, depth); - forEachChildRecursive(node, cbNode, depth + 1); - return res; -} -exports.forEachChildRecursive = forEachChildRecursive; -function syntaxKindToString(syntaxKind) { - return ts.SyntaxKind[syntaxKind]; -} -exports.syntaxKindToString = syntaxKindToString; -function getNodeByKindAndName(program, kind, name) { - var found = undefined; - function findNode(node) { - if (node.kind == kind) { - if (node.kind == ts.SyntaxKind.ClassDeclaration) { - if (node.name.text == name) { - found = node; - } - } - if (node.kind == ts.SyntaxKind.InterfaceDeclaration) { - if (node.name.text == name) { - found = node; - } - } - } - if (!found) { - exports.forEachChild(node, findNode); - } - } - for (var _i = 0, _a = program.getSourceFiles(); _i < _a.length; _i++) { - var file = _a[_i]; - exports.forEachChild(file, findNode); - } - return found; -} -exports.getNodeByKindAndName = getNodeByKindAndName; -function getSourceFileImports(srcFile) { - var modules = []; - getImports(srcFile, modules); - return modules; -} -exports.getSourceFileImports = getSourceFileImports; -function getSourceFileImportsWithTextRange(srcFile) { - var modules = []; - getImportsWithTextRange(srcFile, modules); - return modules; -} -exports.getSourceFileImportsWithTextRange = getSourceFileImportsWithTextRange; -function getImports(searchNode, importedModules) { - ts.forEachChild(searchNode, function (node) { - if (node.kind === ts.SyntaxKind.ImportDeclaration || node.kind === ts.SyntaxKind.ImportEqualsDeclaration || node.kind === ts.SyntaxKind.ExportDeclaration) { - var moduleNameExpr = getExternalModuleName(node); - if (moduleNameExpr && moduleNameExpr.kind === ts.SyntaxKind.StringLiteral) { - importedModules.push(moduleNameExpr.text); - } - } - else if (node.kind === ts.SyntaxKind.ModuleDeclaration && node.name.kind === ts.SyntaxKind.StringLiteral) { - getImports(node.body, importedModules); - } - }); -} -function getExternalModuleName(node) { - if (node.kind === ts.SyntaxKind.ImportDeclaration) { - return node.moduleSpecifier; - } - if (node.kind === ts.SyntaxKind.ImportEqualsDeclaration) { - var reference = node.moduleReference; - if (reference.kind === ts.SyntaxKind.ExternalModuleReference) { - return reference.expression; - } - } - if (node.kind === ts.SyntaxKind.ExportDeclaration) { - return node.moduleSpecifier; - } -} -function getImportsWithTextRange(searchNode, importedModules) { - ts.forEachChild(searchNode, function (node) { - if (node.kind === ts.SyntaxKind.ImportDeclaration || node.kind === ts.SyntaxKind.ImportEqualsDeclaration || node.kind === ts.SyntaxKind.ExportDeclaration) { - var moduleNameExpr = getExternalModuleName(node); - if (moduleNameExpr && moduleNameExpr.kind === ts.SyntaxKind.StringLiteral) { - var moduleExpr = moduleNameExpr; - importedModules.push({ - text: moduleExpr.text, - range: { pos: moduleExpr.getStart() + 1, end: moduleExpr.getEnd() - 1 } - }); - } - } - else if (node.kind === ts.SyntaxKind.ModuleDeclaration && node.name.kind === ts.SyntaxKind.StringLiteral) { - getImportsWithTextRange(node.body, importedModules); - } - }); -} diff --git a/dist/main/lang/fixmyts/quickFix.js b/dist/main/lang/fixmyts/quickFix.js deleted file mode 100644 index d9b265ecf..000000000 --- a/dist/main/lang/fixmyts/quickFix.js +++ /dev/null @@ -1,18 +0,0 @@ -"use strict"; -function getRefactoringsByFilePath(refactorings) { - var loc = {}; - for (var _i = 0, refactorings_1 = refactorings; _i < refactorings_1.length; _i++) { - var refac = refactorings_1[_i]; - if (!loc[refac.filePath]) - loc[refac.filePath] = []; - loc[refac.filePath].push(refac); - } - for (var filePath in loc) { - var refactorings_2 = loc[filePath]; - refactorings_2.sort(function (a, b) { - return (b.span.start - a.span.start); - }); - } - return loc; -} -exports.getRefactoringsByFilePath = getRefactoringsByFilePath; diff --git a/dist/main/lang/fixmyts/quickFixRegistry.js b/dist/main/lang/fixmyts/quickFixRegistry.js deleted file mode 100644 index b7d6ba799..000000000 --- a/dist/main/lang/fixmyts/quickFixRegistry.js +++ /dev/null @@ -1,33 +0,0 @@ -"use strict"; -var addClassMember_1 = require("./quickFixes/addClassMember"); -var addClassMethod_1 = require("./quickFixes/addClassMethod"); -var addImportDefaultStatement_1 = require("./quickFixes/addImportDefaultStatement"); -var addImportFromStatement_1 = require("./quickFixes/addImportFromStatement"); -var addImportStatement_1 = require("./quickFixes/addImportStatement"); -var equalsToEquals_1 = require("./quickFixes/equalsToEquals"); -var extractVariable_1 = require("./quickFixes/extractVariable"); -var wrapInProperty_1 = require("./quickFixes/wrapInProperty"); -var quotesToQuotes_1 = require("./quickFixes/quotesToQuotes"); -var quoteToTemplate_1 = require("./quickFixes/quoteToTemplate"); -var stringConcatToTemplate_1 = require("./quickFixes/stringConcatToTemplate"); -var typeAssertPropertyAccessToAny_1 = require("./quickFixes/typeAssertPropertyAccessToAny"); -var typeAssertPropertyAccessToType_1 = require("./quickFixes/typeAssertPropertyAccessToType"); -var implementInterface_1 = require("./quickFixes/implementInterface"); -var singleLineCommentToJsdoc_1 = require("./quickFixes/singleLineCommentToJsdoc"); -exports.allQuickFixes = [ - new addClassMethod_1.AddClassMethod(), - new addClassMember_1.AddClassMember(), - new addImportDefaultStatement_1.AddImportDefaultStatement(), - new addImportFromStatement_1.AddImportFromStatement(), - new addImportStatement_1.AddImportStatement(), - new wrapInProperty_1.WrapInProperty(), - new equalsToEquals_1.EqualsToEquals(), - new extractVariable_1.ExtractVariable(), - new stringConcatToTemplate_1.StringConcatToTemplate(), - new quotesToQuotes_1.QuotesToQuotes(), - new quoteToTemplate_1.QuoteToTemplate(), - new typeAssertPropertyAccessToAny_1.TypeAssertPropertyAccessToAny(), - new typeAssertPropertyAccessToType_1.TypeAssertPropertyAccessToType(), - new implementInterface_1.ImplementInterface(), - new singleLineCommentToJsdoc_1.SingleLineCommentToJsdoc() -]; diff --git a/dist/main/lang/fixmyts/quickFixes/addClassMember.js b/dist/main/lang/fixmyts/quickFixes/addClassMember.js deleted file mode 100644 index ad3965d46..000000000 --- a/dist/main/lang/fixmyts/quickFixes/addClassMember.js +++ /dev/null @@ -1,88 +0,0 @@ -"use strict"; -var ast = require("../astUtils"); -var os_1 = require("os"); -function getIdentifierAndClassNames(error) { - var errorText = error.messageText; - if (typeof errorText !== 'string') { - console.error('I have no idea what this is:', errorText); - return undefined; - } - ; - var match = errorText.match(/Property \'(\w+)\' does not exist on type \'(\w+)\'./); - if (!match) - return; - var identifierName = match[1], className = match[2]; - return { identifierName: identifierName, className: className }; -} -function getLastNameAfterDot(text) { - return text.substr(text.lastIndexOf('.') + 1); -} -function getTypeStringForNode(node, typeChecker) { - var type = typeChecker.getTypeAtLocation(node); - return ts.displayPartsToString(ts.typeToDisplayParts(typeChecker, type)).replace(/\s+/g, ' '); -} -var AddClassMember = (function () { - function AddClassMember() { - this.key = AddClassMember.name; - } - AddClassMember.prototype.canProvideFix = function (info) { - var relevantError = info.positionErrors.filter(function (x) { return x.code == ts.Diagnostics.Property_0_does_not_exist_on_type_1.code; })[0]; - if (!relevantError) - return; - if (info.positionNode.kind !== ts.SyntaxKind.Identifier) - return; - var match = getIdentifierAndClassNames(relevantError); - if (!match) - return; - var identifierName = match.identifierName, className = match.className; - return { display: "Add " + identifierName + " to " + className }; - }; - AddClassMember.prototype.provideFix = function (info) { - var relevantError = info.positionErrors.filter(function (x) { return x.code == ts.Diagnostics.Property_0_does_not_exist_on_type_1.code; })[0]; - var identifier = info.positionNode; - var identifierName = identifier.text; - var className = getIdentifierAndClassNames(relevantError).className; - var typeString = 'any'; - var parentOfParent = identifier.parent.parent; - if (parentOfParent.kind == ts.SyntaxKind.BinaryExpression - && parentOfParent.operatorToken.getText().trim() == '=') { - var binaryExpression = parentOfParent; - typeString = getTypeStringForNode(binaryExpression.right, info.typeChecker); - } - else if (parentOfParent.kind == ts.SyntaxKind.CallExpression) { - var callExp = parentOfParent; - var typeStringParts = ['(']; - var args_1 = []; - callExp.arguments.forEach(function (arg) { - var argName = (getLastNameAfterDot(arg.getText())); - var argType = getTypeStringForNode(arg, info.typeChecker); - args_1.push(argName + ": " + argType); - }); - typeStringParts.push(args_1.join(', ')); - typeStringParts.push(') => any'); - typeString = typeStringParts.join(''); - } - var memberTarget = ast.getNodeByKindAndName(info.program, ts.SyntaxKind.ClassDeclaration, className); - if (!memberTarget) { - memberTarget = ast.getNodeByKindAndName(info.program, ts.SyntaxKind.InterfaceDeclaration, className); - } - if (!memberTarget) { - return []; - } - var targetDeclaration = memberTarget; - var firstBrace = targetDeclaration.getChildren().filter(function (x) { return x.kind == ts.SyntaxKind.OpenBraceToken; })[0]; - var indentLength = info.service.getIndentationAtPosition(memberTarget.getSourceFile().fileName, firstBrace.end, info.project.projectFile.project.formatCodeOptions); - var indent = Array(indentLength + info.project.projectFile.project.formatCodeOptions.IndentSize + 1).join(' '); - var refactoring = { - span: { - start: firstBrace.end, - length: 0 - }, - newText: "" + os_1.EOL + indent + identifierName + ": " + typeString + ";", - filePath: targetDeclaration.getSourceFile().fileName - }; - return [refactoring]; - }; - return AddClassMember; -}()); -exports.AddClassMember = AddClassMember; diff --git a/dist/main/lang/fixmyts/quickFixes/addClassMethod.js b/dist/main/lang/fixmyts/quickFixes/addClassMethod.js deleted file mode 100644 index b702d1b20..000000000 --- a/dist/main/lang/fixmyts/quickFixes/addClassMethod.js +++ /dev/null @@ -1,154 +0,0 @@ -"use strict"; -var ast = require("../astUtils"); -var os_1 = require("os"); -function getIdentifierAndClassNames(error) { - var errorText = error.messageText; - if (typeof errorText !== 'string') { - console.error('I have no idea what this is:', errorText); - return undefined; - } - ; - var match = errorText.match(/Property \'(\w+)\' does not exist on type \'(\w+)\'./); - if (!match) - return; - var identifierName = match[1], className = match[2]; - return { identifierName: identifierName, className: className }; -} -function getLastNameAfterDot(text) { - return text.substr(text.lastIndexOf('.') + 1); -} -function getTypeStringForNode(node, typeChecker) { - var type = typeChecker.getTypeAtLocation(node); - return ts.displayPartsToString(ts.typeToDisplayParts(typeChecker, type)).replace(/\s+/g, ' '); -} -var AddClassMethod = (function () { - function AddClassMethod() { - this.key = AddClassMethod.name; - } - AddClassMethod.prototype.canProvideFix = function (info) { - var relevantError = info.positionErrors.filter(function (x) { return x.code == ts.Diagnostics.Property_0_does_not_exist_on_type_1.code; })[0]; - if (!relevantError) - return; - if (info.positionNode.kind !== ts.SyntaxKind.Identifier) - return; - var match = getIdentifierAndClassNames(relevantError); - if (!match) - return; - var identifierName = match.identifierName, className = match.className; - return { display: "Add method \"" + identifierName + "\" to current class " + className }; - }; - AddClassMethod.prototype.provideFix = function (info) { - var relevantError = info.positionErrors.filter(function (x) { return x.code == ts.Diagnostics.Property_0_does_not_exist_on_type_1.code; })[0]; - var identifier = info.positionNode; - var identifierName = identifier.text; - var className = getIdentifierAndClassNames(relevantError).className; - var typeString = 'any'; - var parentOfParent = identifier.parent.parent; - if (parentOfParent.kind == ts.SyntaxKind.BinaryExpression - && parentOfParent.operatorToken.getText().trim() == '=') { - var binaryExpression = parentOfParent; - typeString = getTypeStringForNode(binaryExpression.right, info.typeChecker); - } - else if (parentOfParent.kind == ts.SyntaxKind.CallExpression) { - var nativeTypes_1 = ['string', 'number', 'boolean', 'object', 'null', 'undefined', 'RegExp']; - var abc_1 = 'abcdefghijklmnopqrstuvwxyz'; - var argsAlphabet_1 = abc_1.split(''); - var argsAlphabetPosition_1 = 0; - var argName_1 = ''; - var argCount_1 = 0; - var callExp = parentOfParent; - var typeStringParts = ['(']; - var args_1 = []; - callExp.arguments.forEach(function (arg) { - var argType = getTypeStringForNode(arg, info.typeChecker); - if (nativeTypes_1.indexOf(argType) != -1 - || argType.indexOf('{') != -1 - || argType.indexOf('=>') != -1 - || argType.indexOf('[]') != -1) { - var type = info.typeChecker.getTypeAtLocation(arg); - var typeName = "type"; - if (type && - type.symbol && - type.symbol.name) { - typeName = type.symbol.name.replace(/[\[\]]/g, ''); - } - ; - var hasAnonymous = typeName.indexOf('__') == 0; - var isAnonymousTypedArgument = hasAnonymous && typeName.substring(2) == "type"; - var isAnonymousMethod = hasAnonymous && typeName.substring(2) == "function"; - var isAnonymousObject = hasAnonymous && typeName.substring(2) == "object"; - if (argType.indexOf('=>') != -1 && - !isAnonymousTypedArgument && - !isAnonymousMethod && - !isAnonymousObject) { - if (typeName == 'Array') - typeName = 'array'; - argName_1 = "" + typeName + argCount_1++; - } - else if (argType.indexOf('[]') != -1) { - argName_1 = "array" + argCount_1++; - } - else { - if (isAnonymousMethod) { - typeName = "function"; - argName_1 = "" + typeName + argCount_1++; - } - else if (isAnonymousObject) { - typeName = "object"; - argName_1 = "" + typeName + argCount_1++; - } - else { - argName_1 = argsAlphabet_1[argsAlphabetPosition_1]; - argsAlphabet_1[argsAlphabetPosition_1] += argsAlphabet_1[argsAlphabetPosition_1].substring(1); - argsAlphabetPosition_1++; - argsAlphabetPosition_1 %= abc_1.length; - } - } - } - else { - argName_1 = argType.replace('typeof ', ''); - if (argType.indexOf('typeof ') == -1) { - var firstLower = argName_1[0].toLowerCase(); - if (argName_1.length == 1) { - argName_1 = firstLower; - } - else { - argName_1 = firstLower + argName_1.substring(1); - } - } - argName_1 += argCount_1.toString(); - argCount_1++; - } - if (argType.indexOf('null') != -1 || argType.indexOf('undefined') != -1) { - argType = argType.replace(/null|undefined/g, 'any'); - } - args_1.push(argName_1 + ": " + argType); - }); - typeStringParts.push(args_1.join(', ')); - typeStringParts.push("): any { }"); - typeString = typeStringParts.join(''); - } - var memberTarget = ast.getNodeByKindAndName(info.program, ts.SyntaxKind.ClassDeclaration, className); - if (!memberTarget) { - memberTarget = ast.getNodeByKindAndName(info.program, ts.SyntaxKind.InterfaceDeclaration, className); - } - if (!memberTarget) { - return []; - } - var targetDeclaration = memberTarget; - var firstBrace = targetDeclaration.getChildren().filter(function (x) { return x.kind == ts.SyntaxKind.OpenBraceToken; })[0]; - var indentLength = info.service.getIndentationAtPosition(memberTarget.getSourceFile().fileName, firstBrace.end, info.project.projectFile.project.formatCodeOptions); - var indent = Array(indentLength + info.project.projectFile.project.formatCodeOptions.IndentSize + 1).join(' '); - var refactoring = { - span: { - start: firstBrace.end, - length: 0 - }, - newText: "" + os_1.EOL + indent + "public " + identifierName + typeString, - filePath: targetDeclaration.getSourceFile().fileName - }; - return [refactoring]; - }; - return AddClassMethod; -}()); -exports.AddClassMethod = AddClassMethod; diff --git a/dist/main/lang/fixmyts/quickFixes/addImportDefaultStatement.js b/dist/main/lang/fixmyts/quickFixes/addImportDefaultStatement.js deleted file mode 100644 index 1afb1828a..000000000 --- a/dist/main/lang/fixmyts/quickFixes/addImportDefaultStatement.js +++ /dev/null @@ -1,58 +0,0 @@ -"use strict"; -var os_1 = require("os"); -var displayPartsToString = ts.displayPartsToString, typeToDisplayParts = ts.typeToDisplayParts; -var getPathCompletions_1 = require("../../modules/getPathCompletions"); -function getIdentifierAndFileNames(error, project) { - var errorText = error.messageText; - if (typeof errorText !== 'string') { - return undefined; - } - ; - var match = errorText.match(/Cannot find name \'(\w+)\'./); - if (!match) - return; - var identifierName = match[1]; - var files = getPathCompletions_1.getPathCompletions({ - project: project, - filePath: error.file.fileName, - prefix: identifierName, - includeExternalModules: false - }).files; - var file = files.length > 0 ? files[0].relativePath : undefined; - var basename = files.length > 0 ? files[0].name : undefined; - return { identifierName: identifierName, file: file, basename: basename }; -} -var AddImportDefaultStatement = (function () { - function AddImportDefaultStatement() { - this.key = AddImportDefaultStatement.name; - } - AddImportDefaultStatement.prototype.canProvideFix = function (info) { - var relevantError = info.positionErrors.filter(function (x) { return x.code == 2304; })[0]; - if (!relevantError) - return; - if (info.positionNode.kind !== ts.SyntaxKind.Identifier) - return; - var matches = getIdentifierAndFileNames(relevantError, info.project); - if (!matches) - return; - var identifierName = matches.identifierName, file = matches.file; - return file ? { display: "import " + identifierName + " from \"" + file + "\"" } : undefined; - }; - AddImportDefaultStatement.prototype.provideFix = function (info) { - var relevantError = info.positionErrors.filter(function (x) { return x.code == 2304; })[0]; - var identifier = info.positionNode; - var identifierName = identifier.text; - var fileNameforFix = getIdentifierAndFileNames(relevantError, info.project); - var refactorings = [{ - span: { - start: 0, - length: 0 - }, - newText: "import " + identifierName + " from \"" + fileNameforFix.file + "\";" + os_1.EOL, - filePath: info.sourceFile.fileName - }]; - return refactorings; - }; - return AddImportDefaultStatement; -}()); -exports.AddImportDefaultStatement = AddImportDefaultStatement; diff --git a/dist/main/lang/fixmyts/quickFixes/addImportFromStatement.js b/dist/main/lang/fixmyts/quickFixes/addImportFromStatement.js deleted file mode 100644 index ba7e5ba41..000000000 --- a/dist/main/lang/fixmyts/quickFixes/addImportFromStatement.js +++ /dev/null @@ -1,58 +0,0 @@ -"use strict"; -var os_1 = require("os"); -var displayPartsToString = ts.displayPartsToString, typeToDisplayParts = ts.typeToDisplayParts; -var getPathCompletions_1 = require("../../modules/getPathCompletions"); -function getIdentifierAndFileNames(error, project) { - var errorText = error.messageText; - if (typeof errorText !== 'string') { - return undefined; - } - ; - var match = errorText.match(/Cannot find name \'(\w+)\'./); - if (!match) - return; - var identifierName = match[1]; - var files = getPathCompletions_1.getPathCompletions({ - project: project, - filePath: error.file.fileName, - prefix: identifierName, - includeExternalModules: false - }).files; - var file = files.length > 0 ? files[0].relativePath : undefined; - var basename = files.length > 0 ? files[0].name : undefined; - return { identifierName: identifierName, file: file, basename: basename }; -} -var AddImportFromStatement = (function () { - function AddImportFromStatement() { - this.key = AddImportFromStatement.name; - } - AddImportFromStatement.prototype.canProvideFix = function (info) { - var relevantError = info.positionErrors.filter(function (x) { return x.code == 2304; })[0]; - if (!relevantError) - return; - if (info.positionNode.kind !== ts.SyntaxKind.Identifier) - return; - var matches = getIdentifierAndFileNames(relevantError, info.project); - if (!matches) - return; - var identifierName = matches.identifierName, file = matches.file; - return file ? { display: "import {" + identifierName + "} from \"" + file + "\"" } : undefined; - }; - AddImportFromStatement.prototype.provideFix = function (info) { - var relevantError = info.positionErrors.filter(function (x) { return x.code == 2304; })[0]; - var identifier = info.positionNode; - var identifierName = identifier.text; - var fileNameforFix = getIdentifierAndFileNames(relevantError, info.project); - var refactorings = [{ - span: { - start: 0, - length: 0 - }, - newText: "import {" + identifierName + "} from \"" + fileNameforFix.file + "\";" + os_1.EOL, - filePath: info.sourceFile.fileName - }]; - return refactorings; - }; - return AddImportFromStatement; -}()); -exports.AddImportFromStatement = AddImportFromStatement; diff --git a/dist/main/lang/fixmyts/quickFixes/addImportStatement.js b/dist/main/lang/fixmyts/quickFixes/addImportStatement.js deleted file mode 100644 index b690f14f7..000000000 --- a/dist/main/lang/fixmyts/quickFixes/addImportStatement.js +++ /dev/null @@ -1,58 +0,0 @@ -"use strict"; -var os_1 = require("os"); -var displayPartsToString = ts.displayPartsToString, typeToDisplayParts = ts.typeToDisplayParts; -var getPathCompletions_1 = require("../../modules/getPathCompletions"); -function getIdentifierAndFileNames(error, project) { - var errorText = error.messageText; - if (typeof errorText !== 'string') { - return undefined; - } - ; - var match = errorText.match(/Cannot find name \'(\w+)\'./); - if (!match) - return; - var identifierName = match[1]; - var files = getPathCompletions_1.getPathCompletions({ - project: project, - filePath: error.file.fileName, - prefix: identifierName, - includeExternalModules: false - }).files; - var file = files.length > 0 ? files[0].relativePath : undefined; - var basename = files.length > 0 ? files[0].name : undefined; - return { identifierName: identifierName, file: file, basename: basename }; -} -var AddImportStatement = (function () { - function AddImportStatement() { - this.key = AddImportStatement.name; - } - AddImportStatement.prototype.canProvideFix = function (info) { - var relevantError = info.positionErrors.filter(function (x) { return x.code == 2304; })[0]; - if (!relevantError) - return; - if (info.positionNode.kind !== ts.SyntaxKind.Identifier) - return; - var matches = getIdentifierAndFileNames(relevantError, info.project); - if (!matches) - return; - var identifierName = matches.identifierName, file = matches.file; - return file ? { display: "import " + identifierName + " = require(\"" + file + "\")" } : undefined; - }; - AddImportStatement.prototype.provideFix = function (info) { - var relevantError = info.positionErrors.filter(function (x) { return x.code == 2304; })[0]; - var identifier = info.positionNode; - var identifierName = identifier.text; - var fileNameforFix = getIdentifierAndFileNames(relevantError, info.project); - var refactorings = [{ - span: { - start: 0, - length: 0 - }, - newText: "import " + identifierName + " = require(\"" + fileNameforFix.file + "\");" + os_1.EOL, - filePath: info.sourceFile.fileName - }]; - return refactorings; - }; - return AddImportStatement; -}()); -exports.AddImportStatement = AddImportStatement; diff --git a/dist/main/lang/fixmyts/quickFixes/equalsToEquals.js b/dist/main/lang/fixmyts/quickFixes/equalsToEquals.js deleted file mode 100644 index 7175617fe..000000000 --- a/dist/main/lang/fixmyts/quickFixes/equalsToEquals.js +++ /dev/null @@ -1,33 +0,0 @@ -"use strict"; -var EqualsToEquals = (function () { - function EqualsToEquals() { - this.key = EqualsToEquals.name; - } - EqualsToEquals.prototype.canProvideFix = function (info) { - if (info.positionNode.kind === ts.SyntaxKind.EqualsEqualsToken) { - return { display: "Convert == to ===" }; - } - if (info.positionNode.kind === ts.SyntaxKind.ExclamationEqualsToken) { - return { display: "Convert != to !==" }; - } - }; - EqualsToEquals.prototype.provideFix = function (info) { - if (info.positionNode.kind === ts.SyntaxKind.EqualsEqualsToken) { - var newText = '==='; - } - if (info.positionNode.kind === ts.SyntaxKind.ExclamationEqualsToken) { - var newText = '!=='; - } - var refactoring = { - span: { - start: info.positionNode.end - 2, - length: 2 - }, - newText: newText, - filePath: info.filePath - }; - return [refactoring]; - }; - return EqualsToEquals; -}()); -exports.EqualsToEquals = EqualsToEquals; diff --git a/dist/main/lang/fixmyts/quickFixes/extractVariable.js b/dist/main/lang/fixmyts/quickFixes/extractVariable.js deleted file mode 100644 index 7406d3ce3..000000000 --- a/dist/main/lang/fixmyts/quickFixes/extractVariable.js +++ /dev/null @@ -1,179 +0,0 @@ -"use strict"; -var os_1 = require("os"); -var ExtractVariable = (function () { - function ExtractVariable() { - this.key = ExtractVariable.name; - } - ExtractVariable.prototype.canProvideFix = function (info) { - return execute(info, function () { - var identifier = info.positionNode; - return { display: "Extract variable from " + identifier.text }; - }, function () { - var identifier = info.positionNode; - return { display: "Extract variable from " + identifier.text }; - }, function () { - return { display: "Extract variable" }; - }); - }; - ExtractVariable.prototype.provideFix = function (info) { - return execute(info, function () { - return extractVariableFromCall(info); - }, function () { - return extractVariableFromCall(info, "Result"); - }, function (callExpression) { - return extractVariableFromArg(info, callExpression); - }); - }; - return ExtractVariable; -}()); -exports.ExtractVariable = ExtractVariable; -function execute(info, onProperty, onFuncCall, onExtractable) { - var callExpression = findLowestNode(info.positionNode, ts.SyntaxKind.CallExpression); - if (callExpression) { - if (isPropertyCall(info)) { - return onProperty(); - } - else if (isFuncCall(info)) { - return onFuncCall(); - } - else if (isExtractable(info, callExpression)) { - return onExtractable(callExpression); - } - } - else if (isPropertyAccess(info)) { - return onProperty(); - } -} -function extractVariableFromCall(info, postFix) { - if (postFix === void 0) { postFix = ''; } - var typeChecker = info.typeChecker; - var type = getTypeStringForNode(info.positionNode, typeChecker); - var identifier = info.positionNode; - return [{ - span: { - start: startOfLine(info) + indentAtPos(info), - length: 0 - }, - newText: "var " + identifier.text + postFix + ": " + type + " = ", - filePath: info.filePath - }]; -} -function extractVariableFromArg(info, callExpression) { - var argumentIndex = getArgumentIndex(info.positionNode, callExpression); - var _a = getArgumentDescription(callExpression, argumentIndex, info.typeChecker), name = _a.name, type = _a.type; - var indent = indentAtPos(info); - var value = extractValue(info, callExpression); - return [ - { - span: { - start: callExpression.arguments[argumentIndex].getStart(), - length: value.length - }, - newText: name, - filePath: info.filePath - }, - { - span: { - start: startOfLine(info) + indent, - length: 0 - }, - newText: "var " + name + ": " + type + " = " + value + ";" + os_1.EOL + createIndent(indent), - filePath: info.filePath - } - ]; -} -function isPropertyAccess(info) { - return isValidPath(info.positionNode, [ts.SyntaxKind.Identifier, - ts.SyntaxKind.PropertyAccessExpression, - ts.SyntaxKind.ExpressionStatement]); -} -function isFuncCall(info) { - return isValidPath(info.positionNode, [ts.SyntaxKind.Identifier, - ts.SyntaxKind.CallExpression, - ts.SyntaxKind.ExpressionStatement]); -} -function isPropertyCall(info) { - return isValidPath(info.positionNode, [ts.SyntaxKind.Identifier, - ts.SyntaxKind.PropertyAccessExpression, - ts.SyntaxKind.CallExpression, - ts.SyntaxKind.ExpressionStatement]); -} -function isExtractable(info, callExpression) { - var argumentIndex = getArgumentIndex(info.positionNode, callExpression); - return (argumentIndex > -1) && - (!((info.positionNode.kind == ts.SyntaxKind.Identifier) && - (info.positionNode.parent == callExpression))); -} -function findLowestNode(startNode, kind) { - var node = startNode; - var result = new Array(); - while (node) { - if (node.kind == kind) { - result.push(node); - } - node = node.parent; - } - if (result.length == 0) { - return null; - } - else { - return result.reverse()[0]; - } -} -function getArgumentDescription(node, argumentIndex, typeChecker) { - var signature = typeChecker.getResolvedSignature(node); - var argument = signature.parameters[argumentIndex]; - var sigDeclaration = argument.valueDeclaration.type; - return { - name: argument.name.trim(), - type: node.getSourceFile().text.substring(sigDeclaration.pos, sigDeclaration.end).trim() - }; -} -function startOfLine(info) { - var line = info.project.languageServiceHost.getPositionFromIndex(info.filePath, info.position).line; - return info.project.languageServiceHost.getIndexFromPosition(info.filePath, { line: line, col: 0 }); -} -function indentAtPos(info) { - return info.service.getIndentationAtPosition(info.filePath, info.positionNode.pos, info.project.projectFile.project.formatCodeOptions); -} -function createIndent(indent) { - return Array(indent + 1).join(' '); -} -function getTypeStringForNode(node, typeChecker) { - var type = typeChecker.getTypeAtLocation(node); - var typeSignature = ts.displayPartsToString(ts.typeToDisplayParts(typeChecker, type)).replace(/\s+/g, ' '); - var fatArrowPos = typeSignature.indexOf("=>"); - if (fatArrowPos != -1) { - return typeSignature.substr(fatArrowPos + 3).trim(); - } - else { - return typeSignature.trim(); - } -} -function extractValue(info, callExpression) { - var index = getArgumentIndex(info.positionNode, callExpression); - var argNode = callExpression.arguments[index]; - return info.positionNode.getSourceFile().text.substr(argNode.pos, argNode.end - argNode.pos).trim(); -} -function getArgumentIndex(node, callExpression) { - for (var i = 0; i < callExpression.arguments.length; i++) { - var arg = callExpression.arguments[i]; - if ((node.pos >= arg.pos) && (node.end <= arg.end)) { - return i; - } - } - return -1; -} -function isValidPath(startNode, kinds) { - var node = startNode; - for (var i = 0; i < kinds.length; i++) { - if (!(node.kind == kinds[i])) { - return false; - } - node = node.parent; - if (!node) { - return false; - } - } - return true; -} diff --git a/dist/main/lang/fixmyts/quickFixes/implementInterface.js b/dist/main/lang/fixmyts/quickFixes/implementInterface.js deleted file mode 100644 index 8133aa175..000000000 --- a/dist/main/lang/fixmyts/quickFixes/implementInterface.js +++ /dev/null @@ -1,47 +0,0 @@ -"use strict"; -var ast = require("../astUtils"); -var os_1 = require("os"); -function getClassAndInterfaceName(error) { - var errorText = ts.flattenDiagnosticMessageText(error.messageText, os_1.EOL); - var match = errorText.match(/Class \'(\w+)\' incorrectly implements interface \'(\w+)\'./); - if (!match || match.length !== 3) - return; - var className = match[1], interfaceName = match[2]; - return { className: className, interfaceName: interfaceName }; -} -var ImplementInterface = (function () { - function ImplementInterface() { - this.key = ImplementInterface.name; - } - ImplementInterface.prototype.canProvideFix = function (info) { - var relevantError = info.positionErrors.filter(function (x) { return x.code == ts.Diagnostics.Class_0_incorrectly_implements_interface_1.code; })[0]; - if (!relevantError) - return; - if (info.positionNode.kind !== ts.SyntaxKind.Identifier) - return; - var match = getClassAndInterfaceName(relevantError); - if (!match) - return; - var className = match.className, interfaceName = match.interfaceName; - return { display: "Implement members of " + interfaceName + " in " + className }; - }; - ImplementInterface.prototype.provideFix = function (info) { - var relevantError = info.positionErrors.filter(function (x) { return x.code == ts.Diagnostics.Class_0_incorrectly_implements_interface_1.code; })[0]; - if (!relevantError) - return; - if (info.positionNode.kind !== ts.SyntaxKind.Identifier) - return; - var match = getClassAndInterfaceName(relevantError); - var className = match.className, interfaceName = match.interfaceName; - var interfaceTarget = ast.getNodeByKindAndName(info.program, ts.SyntaxKind.InterfaceDeclaration, className); - var classTarget = ast.getNodeByKindAndName(info.program, ts.SyntaxKind.ClassDeclaration, className); - var braces = classTarget.getChildren().filter(function (x) { return x.kind == ts.SyntaxKind.CloseBraceToken; }); - var lastBrace = braces[braces.length - 1]; - var indentLength = info.service.getIndentationAtPosition(classTarget.getSourceFile().fileName, lastBrace.getStart(), info.project.projectFile.project.formatCodeOptions); - var indent = Array(indentLength + info.project.projectFile.project.formatCodeOptions.IndentSize + 1).join(' '); - var refactorings = []; - return refactorings; - }; - return ImplementInterface; -}()); -exports.ImplementInterface = ImplementInterface; diff --git a/dist/main/lang/fixmyts/quickFixes/quoteToTemplate.js b/dist/main/lang/fixmyts/quickFixes/quoteToTemplate.js deleted file mode 100644 index ad1cd7f98..000000000 --- a/dist/main/lang/fixmyts/quickFixes/quoteToTemplate.js +++ /dev/null @@ -1,34 +0,0 @@ -"use strict"; -var QuoteToTemplate = (function () { - function QuoteToTemplate() { - this.key = QuoteToTemplate.name; - } - QuoteToTemplate.prototype.canProvideFix = function (info) { - if (info.positionNode.kind === ts.SyntaxKind.StringLiteral) { - return { display: "Convert to Template String" }; - } - }; - QuoteToTemplate.prototype.provideFix = function (info) { - var text = info.positionNode.getText(); - var quoteCharacter = text.trim()[0]; - var nextQuoteCharacter = '`'; - var quoteRegex = new RegExp(quoteCharacter, 'g'); - var escapedQuoteRegex = new RegExp("\\\\" + quoteCharacter, 'g'); - var nextQuoteRegex = new RegExp(nextQuoteCharacter, 'g'); - var newText = text - .replace(nextQuoteRegex, "\\" + nextQuoteCharacter) - .replace(escapedQuoteRegex, quoteCharacter); - newText = nextQuoteCharacter + newText.substr(1, newText.length - 2) + nextQuoteCharacter; - var refactoring = { - span: { - start: info.positionNode.getStart(), - length: info.positionNode.end - info.positionNode.getStart() - }, - newText: newText, - filePath: info.filePath - }; - return [refactoring]; - }; - return QuoteToTemplate; -}()); -exports.QuoteToTemplate = QuoteToTemplate; diff --git a/dist/main/lang/fixmyts/quickFixes/quotesToQuotes.js b/dist/main/lang/fixmyts/quickFixes/quotesToQuotes.js deleted file mode 100644 index 7b258d6ab..000000000 --- a/dist/main/lang/fixmyts/quickFixes/quotesToQuotes.js +++ /dev/null @@ -1,39 +0,0 @@ -"use strict"; -var QuotesToQuotes = (function () { - function QuotesToQuotes() { - this.key = QuotesToQuotes.name; - } - QuotesToQuotes.prototype.canProvideFix = function (info) { - if (info.positionNode.kind === ts.SyntaxKind.StringLiteral) { - if (info.positionNode.getText().trim()[0] === "'") { - return { display: "Convert ' to \"" }; - } - if (info.positionNode.getText().trim()[0] === "\"") { - return { display: "Convert \" to '" }; - } - } - }; - QuotesToQuotes.prototype.provideFix = function (info) { - var text = info.positionNode.getText(); - var quoteCharacter = text.trim()[0]; - var nextQuoteCharacter = quoteCharacter === "'" ? '"' : "'"; - var quoteRegex = new RegExp(quoteCharacter, 'g'); - var escapedQuoteRegex = new RegExp("\\\\" + quoteCharacter, 'g'); - var nextQuoteRegex = new RegExp(nextQuoteCharacter, 'g'); - var newText = text - .replace(nextQuoteRegex, "\\" + nextQuoteCharacter) - .replace(escapedQuoteRegex, quoteCharacter); - newText = nextQuoteCharacter + newText.substr(1, newText.length - 2) + nextQuoteCharacter; - var refactoring = { - span: { - start: info.positionNode.getStart(), - length: info.positionNode.end - info.positionNode.getStart() - }, - newText: newText, - filePath: info.filePath - }; - return [refactoring]; - }; - return QuotesToQuotes; -}()); -exports.QuotesToQuotes = QuotesToQuotes; diff --git a/dist/main/lang/fixmyts/quickFixes/singleLineCommentToJsdoc.js b/dist/main/lang/fixmyts/quickFixes/singleLineCommentToJsdoc.js deleted file mode 100644 index eadb457f7..000000000 --- a/dist/main/lang/fixmyts/quickFixes/singleLineCommentToJsdoc.js +++ /dev/null @@ -1,44 +0,0 @@ -"use strict"; -var utils = require("../../utils"); -var SingleLineCommentToJsdoc = (function () { - function SingleLineCommentToJsdoc() { - this.key = SingleLineCommentToJsdoc.name; - this.validNodes = utils.createMap([ - ts.SyntaxKind.ExportKeyword, - ts.SyntaxKind.VarKeyword, - ts.SyntaxKind.LetKeyword, - ts.SyntaxKind.ConstKeyword, - ts.SyntaxKind.FunctionKeyword, - ]); - } - SingleLineCommentToJsdoc.prototype.canProvideFix = function (info) { - if (this.validNodes[info.positionNode.kind]) { - var comments = ts.getLeadingCommentRangesOfNode(info.positionNode, info.sourceFile); - if (!comments) - return; - var mapped = comments.map(function (c) { return info.sourceFileText.substring(c.pos, c.end); }); - if (!mapped.length) - return; - var relevantComment = mapped[mapped.length - 1]; - if (relevantComment.startsWith('//')) - return { display: 'Convert comment to jsDoc' }; - } - }; - SingleLineCommentToJsdoc.prototype.provideFix = function (info) { - var comments = ts.getLeadingCommentRangesOfNode(info.positionNode, info.sourceFile); - var relevantComment = comments[comments.length - 1]; - var oldText = info.sourceFileText.substring(relevantComment.pos, relevantComment.end); - var newText = "/** " + oldText.substr(2).trim() + " */"; - var refactoring = { - span: { - start: relevantComment.pos, - length: relevantComment.end - relevantComment.pos - }, - newText: newText, - filePath: info.filePath - }; - return [refactoring]; - }; - return SingleLineCommentToJsdoc; -}()); -exports.SingleLineCommentToJsdoc = SingleLineCommentToJsdoc; diff --git a/dist/main/lang/fixmyts/quickFixes/stringConcatToTemplate.js b/dist/main/lang/fixmyts/quickFixes/stringConcatToTemplate.js deleted file mode 100644 index 3055256ce..000000000 --- a/dist/main/lang/fixmyts/quickFixes/stringConcatToTemplate.js +++ /dev/null @@ -1,89 +0,0 @@ -"use strict"; -function isBinaryAddition(node) { - return (node.kind == ts.SyntaxKind.BinaryExpression && - node.operatorToken.kind == ts.SyntaxKind.PlusToken); -} -function isStringExpression(node, typeChecker) { - var type = typeChecker.getTypeAtLocation(node); - var flags = type.getFlags(); - return !!(flags & ts.TypeFlags.String); -} -function isAPartOfAChainOfStringAdditions(node, typeChecker) { - var largestSumNode = undefined; - while (true) { - if (isBinaryAddition(node) && isStringExpression(node, typeChecker)) { - largestSumNode = node; - } - if (node.kind == ts.SyntaxKind.SourceFile) { - return largestSumNode; - } - node = node.parent; - } -} -var StringConcatToTemplate = (function () { - function StringConcatToTemplate() { - this.backTickCharacter = '`'; - this.backTick = new RegExp(this.backTickCharacter, 'g'); - this.$regex = /\$/g; - this.key = StringConcatToTemplate.name; - } - StringConcatToTemplate.prototype.canProvideFix = function (info) { - var strRoot = isAPartOfAChainOfStringAdditions(info.positionNode, info.typeChecker); - if (strRoot) { - return { display: 'String concatenations to a template string' }; - } - }; - StringConcatToTemplate.prototype.provideFix = function (info) { - var finalOutput = []; - var strRoot = isAPartOfAChainOfStringAdditions(info.positionNode, info.typeChecker); - var current = strRoot; - while (true) { - if (current.kind == ts.SyntaxKind.BinaryExpression) { - var binary = current; - this.appendToFinal(finalOutput, binary.right); - current = binary.left; - } - else { - this.appendToFinal(finalOutput, current); - break; - } - } - var newText = this.backTickCharacter + - finalOutput.join('') + - this.backTickCharacter; - var refactoring = { - span: { - start: strRoot.getStart(), - length: strRoot.end - strRoot.getStart() - }, - newText: newText, - filePath: info.filePath - }; - return [refactoring]; - }; - StringConcatToTemplate.prototype.appendToFinal = function (finalOutput, node) { - if (node.kind == ts.SyntaxKind.StringLiteral) { - var text = node.getText(); - var quoteCharacter = text.trim()[0]; - var quoteRegex = new RegExp(quoteCharacter, 'g'); - var escapedQuoteRegex = new RegExp("\\\\" + quoteCharacter, 'g'); - var newText = text - .replace(this.backTick, "\\" + this.backTickCharacter) - .replace(escapedQuoteRegex, quoteCharacter) - .replace(this.$regex, '\\$'); - newText = newText.substr(1, newText.length - 2); - finalOutput.unshift(newText); - } - else if (node.kind == ts.SyntaxKind.TemplateExpression || node.kind == ts.SyntaxKind.NoSubstitutionTemplateLiteral) { - var text = node.getText(); - text = text.trim(); - text = text.substr(1, text.length - 2); - finalOutput.unshift(text); - } - else { - finalOutput.unshift('${' + node.getText() + '}'); - } - }; - return StringConcatToTemplate; -}()); -exports.StringConcatToTemplate = StringConcatToTemplate; diff --git a/dist/main/lang/fixmyts/quickFixes/typeAssertPropertyAccessToAny.js b/dist/main/lang/fixmyts/quickFixes/typeAssertPropertyAccessToAny.js deleted file mode 100644 index ee6aec2bc..000000000 --- a/dist/main/lang/fixmyts/quickFixes/typeAssertPropertyAccessToAny.js +++ /dev/null @@ -1,48 +0,0 @@ -"use strict"; -var TypeAssertPropertyAccessToAny = (function () { - function TypeAssertPropertyAccessToAny() { - this.key = TypeAssertPropertyAccessToAny.name; - } - TypeAssertPropertyAccessToAny.prototype.canProvideFix = function (info) { - var relevantError = info.positionErrors.filter(function (x) { return x.code == ts.Diagnostics.Property_0_does_not_exist_on_type_1.code; })[0]; - if (!relevantError) - return; - if (info.positionNode.kind !== ts.SyntaxKind.Identifier) - return; - var match = getIdentifierName(info.positionErrorMessages[0]); - if (!match) - return; - var identifierName = match.identifierName; - return { display: "Assert \"any\" for property access \"" + identifierName + "\"" }; - }; - TypeAssertPropertyAccessToAny.prototype.provideFix = function (info) { - var parent = info.positionNode.parent; - if (parent.kind == ts.SyntaxKind.PropertyAccessExpression) { - var propertyAccess = parent; - var idx = propertyAccess.getChildren().indexOf(info.positionNode); - var prev = propertyAccess.getChildAt(idx - 2); - var start = propertyAccess.getStart(); - var end = prev.getEnd(); - var oldText = propertyAccess.getText().substr(0, end - start); - var refactoring = { - filePath: info.filePath, - span: { - start: start, - length: end - start, - }, - newText: "(" + oldText + " as any)" - }; - return [refactoring]; - } - return []; - }; - return TypeAssertPropertyAccessToAny; -}()); -exports.TypeAssertPropertyAccessToAny = TypeAssertPropertyAccessToAny; -function getIdentifierName(errorText) { - var match = /Property \'(\w+)\' does not exist on type \.*/.exec(errorText); - if (!match) - return; - var identifierName = match[1]; - return { identifierName: identifierName }; -} diff --git a/dist/main/lang/fixmyts/quickFixes/typeAssertPropertyAccessToType.js b/dist/main/lang/fixmyts/quickFixes/typeAssertPropertyAccessToType.js deleted file mode 100644 index b831086c8..000000000 --- a/dist/main/lang/fixmyts/quickFixes/typeAssertPropertyAccessToType.js +++ /dev/null @@ -1,49 +0,0 @@ -"use strict"; -var TypeAssertPropertyAccessToType = (function () { - function TypeAssertPropertyAccessToType() { - this.key = TypeAssertPropertyAccessToType.name; - } - TypeAssertPropertyAccessToType.prototype.canProvideFix = function (info) { - var relevantError = info.positionErrors.filter(function (x) { return x.code == ts.Diagnostics.Property_0_does_not_exist_on_type_1.code; })[0]; - if (!relevantError) - return; - if (info.positionNode.kind !== ts.SyntaxKind.Identifier) - return; - var match = getIdentifierName(info.positionErrorMessages[0]); - if (!match) - return; - var identifierName = match.identifierName; - return { display: "Assert for property access \"" + identifierName + "\"", isNewTextSnippet: true }; - }; - TypeAssertPropertyAccessToType.prototype.provideFix = function (info) { - var parent = info.positionNode.parent; - if (parent.kind == ts.SyntaxKind.PropertyAccessExpression) { - var propertyAccess = parent; - var idx = propertyAccess.getChildren().indexOf(info.positionNode); - var prev = propertyAccess.getChildAt(idx - 2); - var start = propertyAccess.getStart(); - var end = prev.getEnd(); - var oldText = propertyAccess.getText().substr(0, end - start); - var refactoring = { - filePath: info.filePath, - span: { - start: start, - length: propertyAccess.name.end - start, - }, - newText: "(" + oldText + " as ${1:any})${2:." + propertyAccess.name.getText() + "}${3}", - isNewTextSnippet: true, - }; - return [refactoring]; - } - return []; - }; - return TypeAssertPropertyAccessToType; -}()); -exports.TypeAssertPropertyAccessToType = TypeAssertPropertyAccessToType; -function getIdentifierName(errorText) { - var match = /Property \'(\w+)\' does not exist on type \.*/.exec(errorText); - if (!match) - return; - var identifierName = match[1]; - return { identifierName: identifierName }; -} diff --git a/dist/main/lang/fixmyts/quickFixes/wrapInProperty.js b/dist/main/lang/fixmyts/quickFixes/wrapInProperty.js deleted file mode 100644 index 84dc66f78..000000000 --- a/dist/main/lang/fixmyts/quickFixes/wrapInProperty.js +++ /dev/null @@ -1,78 +0,0 @@ -"use strict"; -var os_1 = require("os"); -var WrapInProperty = (function () { - function WrapInProperty() { - this.key = WrapInProperty.name; - } - WrapInProperty.prototype.canProvideFix = function (info) { - if (info.positionNode && info.positionNode.parent && - info.positionNode.parent.parent && info.positionNode.parent.parent.symbol && - info.positionNode.parent.parent.symbol && info.positionNode.parent.parent.symbol.name == '__constructor') { - if (info.positionNode.parent.kind == ts.SyntaxKind.Parameter) { - return { display: "Wrap " + info.positionNode.parent.symbol.name + " in a read only property" }; - } - } - }; - WrapInProperty.prototype.provideFix = function (info) { - var classDecl = info.positionNode.parent.parent.parent; - var constructorDecl = info.positionNode.parent.parent; - var paramDecl = info.positionNode.parent; - var symbolName = info.positionNode.parent.symbol.name; - var typeName = getArgumentType(info, paramDecl); - var firstBrace = classDecl.getChildren().filter(function (x) { return x.kind == ts.SyntaxKind.OpenBraceToken; })[0]; - var classIndent = info.service.getIndentationAtPosition(info.filePath, firstBrace.end, info.project.projectFile.project.formatCodeOptions); - var indent = info.project.projectFile.project.formatCodeOptions.IndentSize; - var indentSetting = { - classIndent: classIndent, - indent: indent - }; - var assignemnt = createAssignment(constructorDecl, symbolName, indentSetting, info.filePath); - var property = createProperty(classDecl, symbolName, typeName, indentSetting, info.filePath); - return [assignemnt, property]; - }; - return WrapInProperty; -}()); -exports.WrapInProperty = WrapInProperty; -function createAssignment(constructorDecl, symbolName, indentSetting, filePath) { - var indentLevel2 = createIndent(indentSetting, 2); - var lastBrace = constructorDecl.body.getChildren() - .filter(function (x) { return x.kind == ts.SyntaxKind.CloseBraceToken; }).reverse()[0]; - var newText = "" + os_1.EOL + indentLevel2 + "this._" + symbolName + " = " + symbolName + ";"; - return { - span: { - start: lastBrace.end - (6 + indentSetting.classIndent), - length: 0 - }, - newText: newText, - filePath: filePath - }; -} -function createProperty(classDecl, symbolName, typeName, indentSetting, filePath) { - var indentLevel1 = createIndent(indentSetting, 1); - var indentLevel2 = createIndent(indentSetting, 2); - var newText = "" + os_1.EOL + indentLevel1 + "_" + symbolName + ": " + typeName + ";" + - ("" + os_1.EOL + indentLevel1 + "get " + symbolName + "(): " + typeName + " {") + - ("" + os_1.EOL + indentLevel2 + "return this._" + symbolName + ";") + - ("" + os_1.EOL + indentLevel1 + "}"); - return { - span: { - start: classDecl.end - (2 + indentSetting.classIndent), - length: 0 - }, - newText: newText, - filePath: filePath - }; -} -function createIndent(indentSetting, level) { - return Array(indentSetting.classIndent + (indentSetting.indent * level) + 1).join(' '); -} -function getArgumentType(info, paramDecl) { - if (paramDecl.type) { - var start = paramDecl.type.pos; - var end = paramDecl.type.end; - return info.sourceFile.text.substr(start, (end - start)).trim(); - } - else { - return 'any'; - } -} diff --git a/dist/main/lang/modules/astToText.js b/dist/main/lang/modules/astToText.js deleted file mode 100644 index 06c4ca9f3..000000000 --- a/dist/main/lang/modules/astToText.js +++ /dev/null @@ -1,69 +0,0 @@ -"use strict"; -var astUtils_1 = require("../fixmyts/astUtils"); -function astToText(srcFile) { - var nodeIndex = 0; - function nodeToNodeDisplay(node, depth) { - var kind = astUtils_1.syntaxKindToString(node.kind); - var children = []; - ts.forEachChild(node, function (cNode) { - var child = nodeToNodeDisplay(cNode, depth + 1); - children.push(child); - }); - var ret = { - kind: kind, - children: children, - pos: node.pos, - end: node.end, - depth: depth, - nodeIndex: nodeIndex, - rawJson: prettyJSONNoParent(node) - }; - nodeIndex++; - return ret; - } - var root = nodeToNodeDisplay(srcFile, 0); - return root; -} -exports.astToText = astToText; -function astToTextFull(srcFile) { - var nodeIndex = 0; - function nodeToNodeDisplay(node, depth) { - var kind = astUtils_1.syntaxKindToString(node.kind); - var children = []; - node.getChildren().forEach(function (cNode) { - var child = nodeToNodeDisplay(cNode, depth + 1); - children.push(child); - }); - var ret = { - kind: kind, - children: children, - pos: node.pos, - end: node.end, - depth: depth, - nodeIndex: nodeIndex, - rawJson: prettyJSONNoParent(node) - }; - nodeIndex++; - return ret; - } - var root = nodeToNodeDisplay(srcFile, 0); - return root; -} -exports.astToTextFull = astToTextFull; -function prettyJSONNoParent(object) { - var cache = []; - var value = JSON.stringify(object, function (key, value) { - if (key == 'parent') { - return; - } - if (typeof value === 'object' && value !== null) { - if (cache.indexOf(value) !== -1) { - return; - } - cache.push(value); - } - return value; - }, 4); - cache = null; - return value; -} diff --git a/dist/main/lang/modules/building.js b/dist/main/lang/modules/building.js deleted file mode 100644 index facaaad3e..000000000 --- a/dist/main/lang/modules/building.js +++ /dev/null @@ -1,240 +0,0 @@ -"use strict"; -var mkdirp = require("mkdirp"); -var path = require("path"); -var fs = require("fs"); -var fsUtil_1 = require("../../utils/fsUtil"); -var utils_1 = require("../utils"); -var findup = require('findup'); -var babels = {}; -var babelConfigs = {}; -exports.Not_In_Context = "/* NotInContext */"; -function diagnosticToTSError(diagnostic) { - var filePath = diagnostic.file.fileName; - var startPosition = diagnostic.file.getLineAndCharacterOfPosition(diagnostic.start); - var endPosition = diagnostic.file.getLineAndCharacterOfPosition(diagnostic.start + diagnostic.length); - return { - filePath: filePath, - startPos: { line: startPosition.line, col: startPosition.character }, - endPos: { line: endPosition.line, col: endPosition.character }, - message: ts.flattenDiagnosticMessageText(diagnostic.messageText, '\n'), - preview: diagnostic.file.text.substr(diagnostic.start, diagnostic.length), - }; -} -exports.diagnosticToTSError = diagnosticToTSError; -function emitFile(proj, filePath) { - var services = proj.languageService; - var output = services.getEmitOutput(filePath); - var emitDone = !output.emitSkipped; - var errors = []; - var sourceFile = services.getNonBoundSourceFile(filePath); - var allDiagnostics = services.getCompilerOptionsDiagnostics() - .concat(services.getSyntacticDiagnostics(filePath)) - .concat(services.getSemanticDiagnostics(filePath)); - allDiagnostics.forEach(function (diagnostic) { - if (!diagnostic.file) - return; - var startPosition = diagnostic.file.getLineAndCharacterOfPosition(diagnostic.start); - errors.push(diagnosticToTSError(diagnostic)); - }); - { - var sourceMapContents_1 = {}; - output.outputFiles.forEach(function (o) { - mkdirp.sync(path.dirname(o.name)); - runExternalTranspiler(filePath, sourceFile.text, o, proj, sourceMapContents_1).then(function (additionalEmits) { - if (!sourceMapContents_1[o.name] && !proj.projectFile.project.compilerOptions.noEmit) { - fs.writeFileSync(o.name, o.text, "utf8"); - } - additionalEmits.forEach(function (a) { - mkdirp.sync(path.dirname(a.name)); - fs.writeFileSync(a.name, a.text, "utf8"); - }); - }); - }); - } - var outputFiles = output.outputFiles.map(function (o) { return o.name; }); - if (path.extname(filePath) == '.d.ts') { - outputFiles.push(filePath); - } - return { - sourceFileName: filePath, - outputFiles: outputFiles, - success: emitDone && !errors.length, - errors: errors, - emitError: !emitDone - }; -} -exports.emitFile = emitFile; -function getRawOutput(proj, filePath) { - var services = proj.languageService; - var output; - if (proj.includesSourceFile(filePath)) { - output = services.getEmitOutput(filePath); - } - else { - output = { - outputFiles: [{ name: filePath, text: exports.Not_In_Context, writeByteOrderMark: false }], - emitSkipped: true - }; - } - return output; -} -exports.getRawOutput = getRawOutput; -function getBabelInstance(projectDirectory) { - return new Promise(function (resolve) { - if (!babels[projectDirectory]) { - findup(projectDirectory, 'node_modules/babel-core', function (err, dir) { - if (err) { - findup(projectDirectory, 'node_modules/babel', function (err, dir) { - if (err) { - babels[projectDirectory] = require('babel'); - } - else { - babels[projectDirectory] = require(path.join(dir, 'node_modules/babel')); - } - resolve(babels[projectDirectory]); - }); - } - else { - babels[projectDirectory] = require(path.join(dir, 'node_modules/babel-core')); - resolve(babels[projectDirectory]); - } - }); - } - else { - resolve(babels[projectDirectory]); - } - }).then(function (babel) { - return new Promise(function (resolve) { - findup(projectDirectory, '.babelrc', function (err, dir) { - if (err) - return resolve(babel); - fs.readFile(path.join(dir, '.babelrc'), function (err, data) { - try { - babelConfigs[projectDirectory] = JSON.parse(data.toString()); - } - catch (e) { } - resolve(babel); - }); - }); - }); - }); -} -function runExternalTranspiler(sourceFileName, sourceFileText, outputFile, project, sourceMapContents) { - if (!isJSFile(outputFile.name) && !isJSSourceMapFile(outputFile.name)) { - return Promise.resolve([]); - } - var settings = project.projectFile.project; - var externalTranspiler = settings.externalTranspiler; - if (!externalTranspiler) { - return Promise.resolve([]); - } - if (isJSSourceMapFile(outputFile.name)) { - var sourceMapPayload = JSON.parse(outputFile.text); - var jsFileName = fsUtil_1.consistentPath(path.resolve(path.dirname(outputFile.name), sourceMapPayload.file)); - sourceMapContents[outputFile.name] = { jsFileName: jsFileName, sourceMapPayload: sourceMapPayload }; - return Promise.resolve([]); - } - if (typeof externalTranspiler === 'string') { - externalTranspiler = { - name: externalTranspiler, - options: {} - }; - } - if (typeof externalTranspiler === 'object') { - if (externalTranspiler.name.toLocaleLowerCase() === "babel") { - return getBabelInstance(project.projectFile.projectFileDirectory).then(function (babel) { - var babelOptions = utils_1.assign(babelConfigs[project.projectFile.projectFileDirectory] || {}, externalTranspiler.options || {}, { - filename: outputFile.name - }); - var sourceMapFileName = getJSMapNameForJSFile(outputFile.name); - if (sourceMapContents[sourceMapFileName]) { - babelOptions.inputSourceMap = sourceMapContents[sourceMapFileName].sourceMapPayload; - var baseName = path.basename(sourceFileName); - babelOptions.inputSourceMap.sources = [baseName]; - babelOptions.inputSourceMap.file = baseName; - } - if (settings.compilerOptions.sourceMap) { - babelOptions.sourceMaps = true; - } - if (settings.compilerOptions.inlineSourceMap) { - babelOptions.sourceMaps = "inline"; - } - if (!settings.compilerOptions.removeComments) { - babelOptions.comments = true; - } - var directory = process.cwd(); - process.chdir(project.projectFile.projectFileDirectory); - var babelResult = babel.transform(outputFile.text, babelOptions); - process.chdir(directory); - outputFile.text = babelResult.code; - if (babelResult.map && settings.compilerOptions.sourceMap) { - var additionalEmit = { - name: sourceMapFileName, - text: JSON.stringify(babelResult.map), - writeByteOrderMark: settings.compilerOptions.emitBOM - }; - if (additionalEmit.name === "") { - console.warn("The TypeScript language service did not yet provide a .js.map name for file " + outputFile.name); - return []; - } - return [additionalEmit]; - } - return []; - }); - } - } - function getJSMapNameForJSFile(jsFileName) { - for (var jsMapName in sourceMapContents) { - if (sourceMapContents.hasOwnProperty(jsMapName)) { - if (sourceMapContents[jsMapName].jsFileName === jsFileName) { - return jsMapName; - } - } - } - return ""; - } -} -function isJSFile(fileName) { - return (path.extname(fileName).toLocaleLowerCase() === ".js"); -} -function isJSSourceMapFile(fileName) { - var lastExt = path.extname(fileName); - if (lastExt === ".map") { - return isJSFile(fileName.substr(0, fileName.length - 4)); - } - return false; -} -var dts = require("../../tsconfig/dts-generator"); -function emitDts(proj) { - if (!proj.projectFile.project) - return; - if (proj.projectFile.project.compilerOptions.outFile) - return; - if (!proj.projectFile.project.package) - return; - if (!proj.projectFile.project.package.directory) - return; - if (!proj.projectFile.project.package.definition) - return; - var outFile = path.resolve(proj.projectFile.project.package.directory, './', proj.projectFile.project.package.definition); - var baseDir = proj.projectFile.project.package.directory; - var name = proj.projectFile.project.package.name; - var main = proj.projectFile.project.package.main; - if (main) { - main = name + '/' + fsUtil_1.consistentPath(main.replace('./', '')); - main = main.replace(/\.*.js$/g, ''); - } - var externs = proj.projectFile.project.typings; - var files = proj.projectFile.project.files; - dts.generate({ - baseDir: baseDir, - files: files, - externs: externs, - name: name, - target: proj.projectFile.project.compilerOptions.target, - out: outFile, - main: main, - outDir: proj.projectFile.project.compilerOptions.outDir - }); -} -exports.emitDts = emitDts; diff --git a/dist/main/lang/modules/formatting.js b/dist/main/lang/modules/formatting.js deleted file mode 100644 index ba6d5e8cc..000000000 --- a/dist/main/lang/modules/formatting.js +++ /dev/null @@ -1,27 +0,0 @@ -"use strict"; -function formatDocument(proj, filePath) { - var textChanges = proj.languageService.getFormattingEditsForDocument(filePath, proj.projectFile.project.formatCodeOptions); - var edits = textChanges.map(function (change) { - return { - start: proj.languageServiceHost.getPositionFromIndex(filePath, change.span.start), - end: proj.languageServiceHost.getPositionFromIndex(filePath, change.span.start + change.span.length), - newText: change.newText - }; - }); - return edits; -} -exports.formatDocument = formatDocument; -function formatDocumentRange(proj, filePath, start, end) { - var st = proj.languageServiceHost.getIndexFromPosition(filePath, start); - var ed = proj.languageServiceHost.getIndexFromPosition(filePath, end); - var textChanges = proj.languageService.getFormattingEditsForRange(filePath, st, ed, proj.projectFile.project.formatCodeOptions); - var edits = textChanges.map(function (change) { - return { - start: proj.languageServiceHost.getPositionFromIndex(filePath, change.span.start), - end: proj.languageServiceHost.getPositionFromIndex(filePath, change.span.start + change.span.length), - newText: change.newText - }; - }); - return edits; -} -exports.formatDocumentRange = formatDocumentRange; diff --git a/dist/main/lang/modules/getPathCompletions.js b/dist/main/lang/modules/getPathCompletions.js deleted file mode 100644 index 7461c162a..000000000 --- a/dist/main/lang/modules/getPathCompletions.js +++ /dev/null @@ -1,51 +0,0 @@ -"use strict"; -var path = require("path"); -var tsconfig = require("../../tsconfig/tsconfig"); -var utils = require("../utils"); -var fuzzaldrin = require('fuzzaldrin'); -function getExternalModuleNames(program) { - var entries = []; - program.getSourceFiles().forEach(function (sourceFile) { - ts.forEachChild(sourceFile, function (child) { - if (child.kind === ts.SyntaxKind.ModuleDeclaration && child.name.kind === ts.SyntaxKind.StringLiteral) { - entries.push(child.name.text); - } - }); - }); - return entries; -} -function formatImportPath(sourcePath) { - sourcePath = sourcePath.replace(/\.d$/, ""); - sourcePath = sourcePath.replace(/.*\/node_modules\//, ""); - return sourcePath; -} -function getPathCompletions(query) { - var project = query.project; - var sourceDir = path.dirname(query.filePath); - var filePaths = project.projectFile.project.files.filter(function (p) { return p !== query.filePath; }); - var files = []; - if (query.includeExternalModules) { - var externalModules = getExternalModuleNames(project.languageService.getProgram()); - externalModules.forEach(function (e) { return files.push({ - name: "" + e, - relativePath: e, - fullPath: e - }); }); - } - filePaths.forEach(function (p) { - files.push({ - name: path.basename(p, '.ts'), - relativePath: formatImportPath(tsconfig.removeExt(tsconfig.makeRelativePath(sourceDir, p))), - fullPath: p - }); - }); - var endsInPunctuation = utils.prefixEndsInPunctuation(query.prefix); - if (!endsInPunctuation) - files = fuzzaldrin.filter(files, query.prefix, { key: 'name' }); - var response = { - files: files, - endsInPunctuation: endsInPunctuation - }; - return response; -} -exports.getPathCompletions = getPathCompletions; diff --git a/dist/main/lang/modules/moveFiles.js b/dist/main/lang/modules/moveFiles.js deleted file mode 100644 index daf35ba20..000000000 --- a/dist/main/lang/modules/moveFiles.js +++ /dev/null @@ -1,39 +0,0 @@ -"use strict"; -var astUtils_1 = require("../fixmyts/astUtils"); -var path = require("path"); -var tsconfig_1 = require("../../tsconfig/tsconfig"); -var fsUtil_1 = require("../../utils/fsUtil"); -function getRenameFilesRefactorings(program, oldDirectoryOrFile, newDirectoryOrFile) { - oldDirectoryOrFile = fsUtil_1.consistentPath(oldDirectoryOrFile); - newDirectoryOrFile = fsUtil_1.consistentPath(newDirectoryOrFile); - var oldFileNoExt = tsconfig_1.removeExt(oldDirectoryOrFile); - var newFileNoExt = tsconfig_1.removeExt(newDirectoryOrFile); - var refactorings = []; - var sourceFiles = program.getSourceFiles(); - sourceFiles.forEach(function (sourceFile) { - var imports = astUtils_1.getSourceFileImportsWithTextRange(sourceFile) - .filter(function (fileReference) { return tsconfig_1.pathIsRelative(fileReference.text); }) - .map(function (ref) { - return { - path: fsUtil_1.consistentPath(path.resolve(path.dirname(sourceFile.fileName), ref.text)), - range: ref.range - }; - }); - var matches = imports.filter(function (f) { return f.path == oldFileNoExt; }); - if (matches.length) { - for (var _i = 0, matches_1 = matches; _i < matches_1.length; _i++) { - var match = matches_1[_i]; - refactorings.push({ - filePath: sourceFile.fileName, - span: { - start: match.range.pos, - length: match.range.end - match.range.pos - }, - newText: tsconfig_1.makeRelativePath(path.dirname(sourceFile.fileName), newFileNoExt) - }); - } - } - }); - return refactorings; -} -exports.getRenameFilesRefactorings = getRenameFilesRefactorings; diff --git a/dist/main/lang/modules/programDependencies.js b/dist/main/lang/modules/programDependencies.js deleted file mode 100644 index 0fe6bdd76..000000000 --- a/dist/main/lang/modules/programDependencies.js +++ /dev/null @@ -1,36 +0,0 @@ -"use strict"; -var tsconfig_1 = require("../../tsconfig/tsconfig"); -var fsUtil_1 = require("../../utils/fsUtil"); -var path = require("path"); -var fs = require("fs"); -var astUtils_1 = require("../fixmyts/astUtils"); -function getDependencies(projectFile, program) { - var links = []; - var projectDir = projectFile.projectFileDirectory; - for (var _i = 0, _a = program.getSourceFiles(); _i < _a.length; _i++) { - var file = _a[_i]; - var filePath = file.fileName; - var dir = path.dirname(filePath); - var targets = astUtils_1.getSourceFileImports(file) - .filter(function (fileReference) { return tsconfig_1.pathIsRelative(fileReference); }) - .map(function (fileReference) { - var file = path.resolve(dir, fileReference + '.ts'); - if (!fs.existsSync(file)) { - file = path.resolve(dir, fileReference + '.d.ts'); - } - return file; - }); - for (var _b = 0, targets_1 = targets; _b < targets_1.length; _b++) { - var target = targets_1[_b]; - var targetPath = fsUtil_1.consistentPath(path.relative(projectDir, fsUtil_1.consistentPath(target))); - var sourcePath = fsUtil_1.consistentPath(path.relative(projectDir, filePath)); - links.push({ - sourcePath: sourcePath, - targetPath: targetPath - }); - } - } - return links; -} -Object.defineProperty(exports, "__esModule", { value: true }); -exports.default = getDependencies; diff --git a/dist/main/lang/projectCache.js b/dist/main/lang/projectCache.js deleted file mode 100644 index 839dbd932..000000000 --- a/dist/main/lang/projectCache.js +++ /dev/null @@ -1,164 +0,0 @@ -"use strict"; -var fs = require("fs"); -var path = require("path"); -var tsconfig = require("../tsconfig/tsconfig"); -var project_1 = require("./core/project"); -var fsu = require("../utils/fsUtil"); -var queryParent = require("../../worker/queryParent"); -exports.queryParent = queryParent; -var child; -function fixChild(childInjected) { - child = childInjected; - queryParent.echoNumWithModification = child.sendToIpc(queryParent.echoNumWithModification); - queryParent.getUpdatedTextForUnsavedEditors = child.sendToIpc(queryParent.getUpdatedTextForUnsavedEditors); - queryParent.getOpenEditorPaths = child.sendToIpc(queryParent.getOpenEditorPaths); - queryParent.setConfigurationError = child.sendToIpc(queryParent.setConfigurationError); - queryParent.notifySuccess = child.sendToIpc(queryParent.notifySuccess); - queryParent.buildUpdate = child.sendToIpc(queryParent.buildUpdate); -} -exports.fixChild = fixChild; -function consistentPath(query) { - if (!query.filePath) - return; - query.filePath = fsu.consistentPath(query.filePath); -} -exports.consistentPath = consistentPath; -var projectByProjectFilePath = {}; -var projectByFilePath = {}; -var watchingProjectFile = {}; -function watchProjectFileIfNotDoingItAlready(projectFilePath) { - if (!fs.existsSync(projectFilePath)) { - return; - } - if (watchingProjectFile[projectFilePath]) - return; - watchingProjectFile[projectFilePath] = true; - fs.watch(projectFilePath, { persistent: false }, function () { - if (!fs.existsSync(projectFilePath)) { - var project = projectByProjectFilePath[projectFilePath]; - if (project) { - var files = project.projectFile.project.files; - delete projectByProjectFilePath[projectFilePath]; - files.forEach(function (file) { return delete projectByFilePath[file]; }); - } - return; - } - try { - var projectFile = getOrCreateProjectFile(projectFilePath); - cacheAndCreateProject(projectFile); - queryParent.setConfigurationError({ projectFilePath: projectFile.projectFilePath, error: null }); - } - catch (ex) { - } - }); -} -function cacheAndCreateProject(projectFile) { - var project = projectByProjectFilePath[projectFile.projectFilePath] = new project_1.Project(projectFile); - projectFile.project.files.forEach(function (file) { return projectByFilePath[file] = project; }); - queryParent.getUpdatedTextForUnsavedEditors({}) - .then(function (resp) { - resp.editors.forEach(function (e) { - consistentPath(e); - project.languageServiceHost.updateScript(e.filePath, e.text); - }); - }); - watchProjectFileIfNotDoingItAlready(projectFile.projectFilePath); - return project; -} -exports.cacheAndCreateProject = cacheAndCreateProject; -function getOrCreateProjectFile(filePath) { - try { - if (path.dirname(filePath) == project_1.languageServiceHost.typescriptDirectory) { - return tsconfig.getDefaultInMemoryProject(filePath); - } - var projectFile = tsconfig.getProjectSync(filePath); - queryParent.setConfigurationError({ projectFilePath: projectFile.projectFilePath, error: null }); - return projectFile; - } - catch (ex) { - var err = ex; - if (err.message === tsconfig.errors.GET_PROJECT_NO_PROJECT_FOUND) { - if (tsconfig.endsWith(filePath.toLowerCase(), '.d.ts')) { - return tsconfig.getDefaultInMemoryProject(filePath); - } - else { - var details = ex.details; - queryParent.setConfigurationError({ - projectFilePath: details.projectFilePath, - error: { - message: ex.message, - details: ex.details - } - }); - } - } - if (ex.message === tsconfig.errors.GET_PROJECT_JSON_PARSE_FAILED) { - var details0 = ex.details; - queryParent.setConfigurationError({ - projectFilePath: details0.projectFilePath, - error: { - message: ex.message, - details: ex.details - } - }); - watchProjectFileIfNotDoingItAlready(details0.projectFilePath); - } - if (ex.message === tsconfig.errors.GET_PROJECT_PROJECT_FILE_INVALID_OPTIONS) { - var details1 = ex.details; - queryParent.setConfigurationError({ - projectFilePath: details1.projectFilePath, - error: { - message: ex.message, - details: ex.details - } - }); - watchProjectFileIfNotDoingItAlready(details1.projectFilePath); - } - if (ex.message === tsconfig.errors.GET_PROJECT_GLOB_EXPAND_FAILED) { - var details2 = ex.details; - queryParent.setConfigurationError({ - projectFilePath: details2.projectFilePath, - error: { - message: ex.message, - details: ex.details - } - }); - watchProjectFileIfNotDoingItAlready(details2.projectFilePath); - } - throw ex; - } -} -exports.getOrCreateProjectFile = getOrCreateProjectFile; -function getOrCreateProject(filePath) { - if (tsconfig.endsWith(filePath, '.tst')) { - filePath = filePath + '.ts'; - } - filePath = fsu.consistentPath(filePath); - if (projectByFilePath[filePath]) { - return projectByFilePath[filePath]; - } - else { - var projectFile = getOrCreateProjectFile(filePath); - var project = cacheAndCreateProject(projectFile); - return project; - } -} -exports.getOrCreateProject = getOrCreateProject; -function resetCache(query) { - projectByProjectFilePath = {}; - projectByFilePath = {}; - if (query.filePath) { - consistentPath(query); - var project = getOrCreateProject(query.filePath); - project.languageServiceHost.updateScript(query.filePath, query.text); - } - queryParent.getUpdatedTextForUnsavedEditors({}) - .then(function (resp) { - resp.editors.forEach(function (e) { - consistentPath(e); - var proj = getOrCreateProject(e.filePath); - proj.languageServiceHost.updateScript(e.filePath, e.text); - }); - }); -} -exports.resetCache = resetCache; diff --git a/dist/main/lang/projectService.js b/dist/main/lang/projectService.js index bb666d38c..db93d32ae 100644 --- a/dist/main/lang/projectService.js +++ b/dist/main/lang/projectService.js @@ -1,16 +1,17 @@ "use strict"; -var fsu = require("../utils/fsUtil"); -var fs = require("fs"); -var path = require("path"); -var os = require("os"); -var child_process = require("child_process"); +Object.defineProperty(exports, "__esModule", { value: true }); +const fsu = require("../utils/fsUtil"); +const fs = require("fs"); +const path = require("path"); +const os = require("os"); +const child_process = require("child_process"); var fuzzaldrin = require('fuzzaldrin'); -var transformer_1 = require("./transformers/transformer"); -var transformer = require("./transformers/transformer"); -var tsconfig = require("../tsconfig/tsconfig"); -var utils = require("./utils"); +const transformer_1 = require("./transformers/transformer"); +const transformer = require("./transformers/transformer"); +const tsconfig = require("../tsconfig/tsconfig"); +const utils = require("./utils"); var resolve = Promise.resolve.bind(Promise); -var projectCache_1 = require("./projectCache"); +const projectCache_1 = require("./projectCache"); function textSpan(span) { return { start: span.start, @@ -18,7 +19,7 @@ function textSpan(span) { }; } function echo(data) { - return projectCache_1.queryParent.echoNumWithModification({ num: data.num }).then(function (resp) { + return projectCache_1.queryParent.echoNumWithModification({ num: data.num }).then((resp) => { data.num = resp.num; return data; }); @@ -43,33 +44,36 @@ function quickInfo(query) { } } exports.quickInfo = quickInfo; -var building = require("./modules/building"); +const building = require("./modules/building"); function build(query) { projectCache_1.consistentPath(query); var proj = projectCache_1.getOrCreateProject(query.filePath); - var filesToEmit = proj.projectFile.project.files.filter(function (fte) { return !fte.toLowerCase().endsWith('.json'); }); + let filesToEmit = proj.projectFile.project.files.filter(fte => !fte.toLowerCase().endsWith('.json')); + /** I am assuming there was at least one file. How else would we even get here? */ filesToEmit = proj.projectFile.project.compilerOptions.outFile ? [filesToEmit[0]] : filesToEmit; - var totalCount = filesToEmit.length; + let totalCount = filesToEmit.length; var builtCount = 0; var errorCount = 0; - var outputs = filesToEmit.map(function (filePath) { + let outputs = filesToEmit.map((filePath) => { var output = building.emitFile(proj, filePath); builtCount++; errorCount = errorCount + output.errors.length; projectCache_1.queryParent.buildUpdate({ - totalCount: totalCount, - builtCount: builtCount, - errorCount: errorCount, + totalCount, + builtCount, + errorCount, firstError: errorCount && !(errorCount - output.errors.length), - filePath: filePath, + filePath, errorsInFile: output.errors }); return output; }); + // Also optionally emit a root dts: building.emitDts(proj); + // If there is a post build script to run ... run it if (proj.projectFile.project.scripts && proj.projectFile.project.scripts.postbuild) { - child_process.exec(proj.projectFile.project.scripts.postbuild, { cwd: proj.projectFile.projectFileDirectory }, function (err, stdout, stderr) { + child_process.exec(proj.projectFile.project.scripts.postbuild, { cwd: proj.projectFile.projectFileDirectory }, (err, stdout, stderr) => { if (err) { console.error('postbuild failed!'); console.error(proj.projectFile.project.scripts.postbuild); @@ -77,12 +81,12 @@ function build(query) { } }); } - var tsFilesWithInvalidEmit = outputs - .filter(function (o) { return o.emitError; }) - .map(function (o) { return o.sourceFileName; }); - var tsFilesWithValidEmit = outputs - .filter(function (o) { return !o.emitError; }) - .map(function (o) { return o.sourceFileName; }); + let tsFilesWithInvalidEmit = outputs + .filter((o) => o.emitError) + .map((o) => o.sourceFileName); + let tsFilesWithValidEmit = outputs + .filter((o) => !o.emitError) + .map((o) => o.sourceFileName); return resolve({ tsFilesWithInvalidEmit: tsFilesWithInvalidEmit, tsFilesWithValidEmit: tsFilesWithValidEmit, @@ -90,9 +94,9 @@ function build(query) { outputs: outputs, counts: { inputFiles: proj.projectFile.project.files.length, - outputFiles: utils.selectMany(outputs.map(function (out) { return out.outputFiles; })).length, + outputFiles: utils.selectMany(outputs.map((out) => out.outputFiles)).length, errors: errorCount, - emitErrors: outputs.filter(function (out) { return out.emitError; }).length + emitErrors: outputs.filter(out => out.emitError).length } } }); @@ -102,22 +106,30 @@ function getCompletionsAtPosition(query) { projectCache_1.consistentPath(query); var filePath = query.filePath, position = query.position, prefix = query.prefix; var project = projectCache_1.getOrCreateProject(filePath); + // For transformer files filePath = transformer.getPseudoFilePath(filePath); var completions = project.languageService.getCompletionsAtPosition(filePath, position); - var completionList = completions ? completions.entries.filter(function (x) { return !!x; }) : []; + var completionList = completions ? completions.entries.filter(x => !!x) : []; var endsInPunctuation = utils.prefixEndsInPunctuation(prefix); if (prefix.length && !endsInPunctuation) { + // Didn't work good for punctuation completionList = fuzzaldrin.filter(completionList, prefix, { key: 'name' }); } - var maxSuggestions = 50; - var maxDocComments = 10; + /** Doing too many suggestions is slowing us down in some cases */ + let maxSuggestions = 50; + /** Doc comments slow us down tremendously */ + let maxDocComments = 10; + // limit to maxSuggestions if (completionList.length > maxSuggestions) completionList = completionList.slice(0, maxSuggestions); + // Potentially use it more aggresively at some point function docComment(c) { var completionDetails = project.languageService.getCompletionEntryDetails(filePath, position, c.name); + // Show the signatures for methods / functions var display; if (c.kind == "method" || c.kind == "function" || c.kind == "property") { - var parts = completionDetails.displayParts || []; + let parts = completionDetails.displayParts || []; + // don't show `(method)` or `(function)` as that is taken care of by `kind` if (parts.length > 3) { parts = parts.splice(3); } @@ -129,7 +141,7 @@ function getCompletionsAtPosition(query) { var comment = (display ? display + '\n' : '') + ts.displayPartsToString(completionDetails.documentation || []); return { display: display, comment: comment }; } - var completionsToReturn = completionList.map(function (c, index) { + var completionsToReturn = completionList.map((c, index) => { if (index < maxDocComments) { var details = docComment(c); } @@ -149,18 +161,19 @@ function getCompletionsAtPosition(query) { if (query.prefix == '(') { var signatures = project.languageService.getSignatureHelpItems(query.filePath, query.position); if (signatures && signatures.items) { - signatures.items.forEach(function (item) { - var snippet = item.parameters.map(function (p, i) { + signatures.items.forEach((item) => { + var snippet = item.parameters.map((p, i) => { var display = '${' + (i + 1) + ':' + ts.displayPartsToString(p.displayParts) + '}'; if (i === signatures.argumentIndex) { return display; } return display; }).join(ts.displayPartsToString(item.separatorDisplayParts)); + // We do not use the label for now. But it looks too good to kill off var label = ts.displayPartsToString(item.prefixDisplayParts) + snippet + ts.displayPartsToString(item.suffixDisplayParts); - completionsToReturn.unshift({ snippet: snippet }); + completionsToReturn.unshift({ snippet }); }); } } @@ -176,6 +189,7 @@ function getSignatureHelps(query) { var signatureHelpItems = project.languageService.getSignatureHelpItems(query.filePath, query.position); if (!signatureHelpItems || !signatureHelpItems.items || !signatureHelpItems.items.length) return resolve({ signatureHelps: [] }); + // TODO: WIP return signatureHelpItems.items; } exports.getSignatureHelps = getSignatureHelps; @@ -185,7 +199,7 @@ function emitFile(query) { return resolve(building.emitFile(projectCache_1.getOrCreateProject(filePath), filePath)); } exports.emitFile = emitFile; -var formatting = require("./modules/formatting"); +const formatting = require("./modules/formatting"); function formatDocument(query) { projectCache_1.consistentPath(query); var proj = projectCache_1.getOrCreateProject(query.filePath); @@ -207,7 +221,8 @@ function getDefinitionsAtPosition(query) { return resolve({ projectFileDirectory: projectFileDirectory, definitions: [] }); return resolve({ projectFileDirectory: projectFileDirectory, - definitions: definitions.map(function (d) { + definitions: definitions.map(d => { + // If we can get the filename *we are in the same program :P* var pos = project.languageServiceHost.getPositionFromIndex(d.fileName, d.textSpan.start); return { filePath: d.fileName, @@ -220,6 +235,7 @@ exports.getDefinitionsAtPosition = getDefinitionsAtPosition; function updateText(query) { projectCache_1.consistentPath(query); var lsh = projectCache_1.getOrCreateProject(query.filePath).languageServiceHost; + // Apply the update to the pseudo ts file var filePath = transformer.getPseudoFilePath(query.filePath); lsh.updateScript(filePath, query.text); return resolve({}); @@ -227,15 +243,17 @@ function updateText(query) { exports.updateText = updateText; function editText(query) { projectCache_1.consistentPath(query); - var project = projectCache_1.getOrCreateProject(query.filePath); + let project = projectCache_1.getOrCreateProject(query.filePath); if (project.includesSourceFile(query.filePath)) { - var lsh = project.languageServiceHost; - var filePath = transformer.getPseudoFilePath(query.filePath); + let lsh = project.languageServiceHost; + // Apply the update to the pseudo ts file + let filePath = transformer.getPseudoFilePath(query.filePath); lsh.editScript(filePath, query.start, query.end, query.newText); } return resolve({}); } exports.editText = editText; +/** Utility function */ function getDiagnositcsByFilePath(query) { projectCache_1.consistentPath(query); var project = projectCache_1.getOrCreateProject(query.filePath); @@ -247,23 +265,24 @@ function getDiagnositcsByFilePath(query) { } function errorsForFile(query) { projectCache_1.consistentPath(query); - var project; + let project; try { project = projectCache_1.getOrCreateProject(query.filePath); } catch (ex) { return resolve({ errors: [] }); } + // for file path errors in transformer if (transformer_1.isTransformerFile(query.filePath)) { - var filePath = transformer.getPseudoFilePath(query.filePath); - var errors = getDiagnositcsByFilePath({ filePath: filePath }).map(building.diagnosticToTSError); - errors.forEach(function (error) { + let filePath = transformer.getPseudoFilePath(query.filePath); + let errors = getDiagnositcsByFilePath({ filePath }).map(building.diagnosticToTSError); + errors.forEach(error => { error.filePath = query.filePath; }); return resolve({ errors: errors }); } else { - var result = void 0; + let result; if (project.includesSourceFile(query.filePath)) { result = getDiagnositcsByFilePath(query).map(building.diagnosticToTSError); } @@ -291,9 +310,10 @@ function getRenameInfo(query) { if (info && info.canRename) { var locations = {}; project.languageService.findRenameLocations(query.filePath, query.position, findInStrings, findInComments) - .forEach(function (loc) { + .forEach(loc => { if (!locations[loc.fileName]) locations[loc.fileName] = []; + // Using unshift makes them with maximum value on top ;) locations[loc.fileName].unshift(textSpan(loc.textSpan)); }); return resolve({ @@ -318,7 +338,7 @@ function getIndentationAtPosition(query) { projectCache_1.consistentPath(query); var project = projectCache_1.getOrCreateProject(query.filePath); var indent = project.languageService.getIndentationAtPosition(query.filePath, query.position, project.projectFile.project.formatCodeOptions); - return resolve({ indent: indent }); + return resolve({ indent }); } exports.getIndentationAtPosition = getIndentationAtPosition; function debugLanguageServiceHostVersion(query) { @@ -334,14 +354,19 @@ function getProjectFileDetails(query) { } exports.getProjectFileDetails = getProjectFileDetails; function sortNavbarItemsBySpan(items) { - items.sort(function (a, b) { return a.spans[0].start - b.spans[0].start; }); - for (var _i = 0, items_1 = items; _i < items_1.length; _i++) { - var item = items_1[_i]; + items.sort((a, b) => a.spans[0].start - b.spans[0].start); + // sort children recursively + for (let item of items) { if (item.childItems) { sortNavbarItemsBySpan(item.childItems); } } } +/** + * Note the `indent` is fairly useless in ts service + * Basically only exists for global / module level and 0 elsewhere + * We make it true indent here ;) + */ function flattenNavBarItems(items) { var toreturn = []; function keepAdding(item, depth) { @@ -350,10 +375,11 @@ function flattenNavBarItems(items) { delete item.childItems; toreturn.push(item); if (children) { - children.forEach(function (child) { return keepAdding(child, depth + 1); }); + children.forEach(child => keepAdding(child, depth + 1)); } } - items.forEach(function (item) { return keepAdding(item, 0); }); + // Kick it off + items.forEach(item => keepAdding(item, 0)); return toreturn; } function getNavigationBarItems(query) { @@ -361,17 +387,21 @@ function getNavigationBarItems(query) { var project = projectCache_1.getOrCreateProject(query.filePath); var languageService = project.languageService; var navBarItems = languageService.getNavigationBarItems(query.filePath); + // remove the first global (whatever that is???) if (navBarItems.length && navBarItems[0].text == "") { navBarItems.shift(); } + // Sort items by first spans: sortNavbarItemsBySpan(navBarItems); + // And flatten navBarItems = flattenNavBarItems(navBarItems); - var items = navBarItems.map(function (item) { + // Add a position + var items = navBarItems.map(item => { item.position = project.languageServiceHost.getPositionFromIndex(query.filePath, item.spans[0].start); delete item.spans; return item; }); - return resolve({ items: items }); + return resolve({ items }); } exports.getNavigationBarItems = getNavigationBarItems; function navigationBarItemToSemanticTreeNode(item, project, query) { @@ -381,7 +411,7 @@ function navigationBarItemToSemanticTreeNode(item, project, query) { kindModifiers: item.kindModifiers, start: project.languageServiceHost.getPositionFromIndex(query.filePath, item.spans[0].start), end: project.languageServiceHost.getPositionFromIndex(query.filePath, item.spans[0].start + item.spans[0].length), - subNodes: item.childItems ? item.childItems.map(function (ci) { return navigationBarItemToSemanticTreeNode(ci, project, query); }) : [] + subNodes: item.childItems ? item.childItems.map(ci => navigationBarItemToSemanticTreeNode(ci, project, query)) : [] }; return toReturn; } @@ -389,26 +419,29 @@ function getSemtanticTree(query) { projectCache_1.consistentPath(query); var project = projectCache_1.getOrCreateProject(query.filePath); var navBarItems = project.languageService.getNavigationBarItems(query.filePath); + // remove the first global (whatever that is???) if (navBarItems.length && navBarItems[0].text == "") { navBarItems.shift(); } + // Sort items by first spans: sortNavbarItemsBySpan(navBarItems); - var nodes = navBarItems.map(function (nbi) { return navigationBarItemToSemanticTreeNode(nbi, project, query); }); - return resolve({ nodes: nodes }); + // convert to SemanticTreeNodes + var nodes = navBarItems.map(nbi => navigationBarItemToSemanticTreeNode(nbi, project, query)); + return resolve({ nodes }); } exports.getSemtanticTree = getSemtanticTree; function getNavigateToItems(query) { projectCache_1.consistentPath(query); var project = projectCache_1.getOrCreateProject(query.filePath); var languageService = project.languageService; - var getNodeKind = ts.getNodeKind; + let getNodeKind = ts.getNodeKind; function getDeclarationName(declaration) { - var result = getTextOfIdentifierOrLiteral(declaration.name); + let result = getTextOfIdentifierOrLiteral(declaration.name); if (result !== undefined) { return result; } if (declaration.name.kind === ts.SyntaxKind.ComputedPropertyName) { - var expr = declaration.name.expression; + let expr = declaration.name.expression; if (expr.kind === ts.SyntaxKind.PropertyAccessExpression) { return expr.name.text; } @@ -425,13 +458,11 @@ function getNavigateToItems(query) { return undefined; } var items = []; - for (var _i = 0, _a = project.getProjectSourceFiles(); _i < _a.length; _i++) { - var file = _a[_i]; - var declarations = file.getNamedDeclarations(); - for (var index in declarations) { - for (var _b = 0, _c = declarations[index]; _b < _c.length; _b++) { - var declaration = _c[_b]; - var item = { + for (let file of project.getProjectSourceFiles()) { + let declarations = file.getNamedDeclarations(); + for (let index in declarations) { + for (let declaration of declarations[index]) { + let item = { name: getDeclarationName(declaration), kind: getNodeKind(declaration), filePath: file.fileName, @@ -442,7 +473,7 @@ function getNavigateToItems(query) { } } } - return resolve({ items: items }); + return resolve({ items }); } exports.getNavigateToItems = getNavigateToItems; function getReferences(query) { @@ -451,16 +482,19 @@ function getReferences(query) { var languageService = project.languageService; var references = []; var refs = languageService.getReferencesAtPosition(query.filePath, query.position) || []; - references = refs.map(function (r) { + references = refs.map(r => { var res = project.languageServiceHost.getPositionFromTextSpanWithLinePreview(r.fileName, r.textSpan); return { filePath: r.fileName, position: res.position, preview: res.preview }; }); return resolve({ - references: references + references }); } exports.getReferences = getReferences; -var getPathCompletions_1 = require("./modules/getPathCompletions"); +/** + * Get Completions for external modules + references tags + */ +const getPathCompletions_1 = require("./modules/getPathCompletions"); function filePathWithoutExtension(query) { var base = path.basename(query, '.ts'); return path.dirname(query) + '/' + base; @@ -469,61 +503,73 @@ function getRelativePathsInProject(query) { projectCache_1.consistentPath(query); var project = projectCache_1.getOrCreateProject(query.filePath); return resolve(getPathCompletions_1.getPathCompletions({ - project: project, + project, filePath: query.filePath, prefix: query.prefix, includeExternalModules: query.includeExternalModules })); } exports.getRelativePathsInProject = getRelativePathsInProject; -var astToText_1 = require("./modules/astToText"); +/** + * Get AST + */ +const astToText_1 = require("./modules/astToText"); function getAST(query) { projectCache_1.consistentPath(query); var project = projectCache_1.getOrCreateProject(query.filePath); var service = project.languageService; - var files = service.getProgram().getSourceFiles().filter(function (x) { return x.fileName == query.filePath; }); + var files = service.getProgram().getSourceFiles().filter(x => x.fileName == query.filePath); if (!files.length) resolve({}); var sourceFile = files[0]; var root = astToText_1.astToText(sourceFile); - return resolve({ root: root }); + return resolve({ root }); } exports.getAST = getAST; function getASTFull(query) { projectCache_1.consistentPath(query); var project = projectCache_1.getOrCreateProject(query.filePath); var service = project.languageService; - var files = service.getProgram().getSourceFiles().filter(function (x) { return x.fileName == query.filePath; }); + var files = service.getProgram().getSourceFiles().filter(x => x.fileName == query.filePath); if (!files.length) resolve({}); var sourceFile = files[0]; var root = astToText_1.astToTextFull(sourceFile); - return resolve({ root: root }); + return resolve({ root }); } exports.getASTFull = getASTFull; -var programDependencies_1 = require("./modules/programDependencies"); +/** + * Get Dependencies + */ +const programDependencies_1 = require("./modules/programDependencies"); function getDependencies(query) { projectCache_1.consistentPath(query); var project = projectCache_1.getOrCreateProject(query.filePath); var projectFile = project.projectFile; var links = programDependencies_1.default(projectFile, project.languageService.getProgram()); - return resolve({ links: links }); + return resolve({ links }); } exports.getDependencies = getDependencies; -var qf = require("./fixmyts/quickFix"); -var quickFixRegistry_1 = require("./fixmyts/quickFixRegistry"); +const qf = require("./fixmyts/quickFix"); +const quickFixRegistry_1 = require("./fixmyts/quickFixRegistry"); function getInfoForQuickFixAnalysis(query) { projectCache_1.consistentPath(query); - var project = projectCache_1.getOrCreateProject(query.filePath); - var program = project.languageService.getProgram(); - var sourceFile = program.getSourceFile(query.filePath); - var sourceFileText, fileErrors, positionErrors, positionErrorMessages, positionNode; + let project = projectCache_1.getOrCreateProject(query.filePath); + let program = project.languageService.getProgram(); + let sourceFile = program.getSourceFile(query.filePath); + let sourceFileText, fileErrors, positionErrors, positionErrorMessages, positionNode; if (project.includesSourceFile(query.filePath)) { sourceFileText = sourceFile.getFullText(); fileErrors = getDiagnositcsByFilePath(query); - positionErrors = fileErrors.filter(function (e) { return ((e.start - 1) < query.position) && (e.start + e.length + 1) > query.position; }); - positionErrorMessages = positionErrors.map(function (e) { return ts.flattenDiagnosticMessageText(e.messageText, os.EOL); }); - positionNode = ts.getTokenAtPosition(sourceFile, query.position); + let position = query.position; + positionErrors = getPositionErrors(fileErrors, position); + if (positionErrors.length === 0 && fileErrors.length !== 0) { + /** Fall back to file errors */ + position = findClosestErrorPosition(fileErrors, position); + positionErrors = getPositionErrors(fileErrors, position); + } + positionErrorMessages = positionErrors.map(e => ts.flattenDiagnosticMessageText(e.messageText, os.EOL)); + positionNode = ts.getTokenAtPosition(sourceFile, position); } else { sourceFileText = ""; @@ -532,23 +578,33 @@ function getInfoForQuickFixAnalysis(query) { positionErrorMessages = []; positionNode = undefined; } - var service = project.languageService; - var typeChecker = program.getTypeChecker(); + let service = project.languageService; + let typeChecker = program.getTypeChecker(); return { - project: project, - program: program, - sourceFile: sourceFile, - sourceFileText: sourceFileText, - fileErrors: fileErrors, - positionErrors: positionErrors, - positionErrorMessages: positionErrorMessages, + project, + program, + sourceFile, + sourceFileText, + fileErrors, + positionErrors, + positionErrorMessages, position: query.position, - positionNode: positionNode, - service: service, - typeChecker: typeChecker, + positionNode, + service, + typeChecker, filePath: query.filePath }; } +function getPositionErrors(fileErrors, position) { + /** We want errors that are *touching* and thefore expand the query position by one */ + return fileErrors.filter(e => ((e.start - 1) < position) && (e.start + e.length + 1) > position); +} +function findClosestErrorPosition(fileErrors, position) { + const newPos = fileErrors + .map(i => [Math.min(Math.abs(position - i.start), Math.abs(position - i.start - i.length)), i.start]) + .reduce((acc, val) => val[0] < acc[0] || acc[0] === -1 ? val : acc, [-1, -1]); + return newPos[1] !== -1 ? newPos[1] : position; +} function getQuickFixes(query) { projectCache_1.consistentPath(query); var project = projectCache_1.getOrCreateProject(query.filePath); @@ -556,28 +612,30 @@ function getQuickFixes(query) { return resolve({ fixes: [] }); } var info = getInfoForQuickFixAnalysis(query); + // And then we let the quickFix determine if it wants provide any fixes for this file + // And if so we also treat the result as a display string var fixes = quickFixRegistry_1.allQuickFixes - .map(function (x) { + .map(x => { var canProvide = x.canProvideFix(info); if (!canProvide) return; else return { key: x.key, display: canProvide.display, isNewTextSnippet: canProvide.isNewTextSnippet }; }) - .filter(function (x) { return !!x; }); - return resolve({ fixes: fixes }); + .filter(x => !!x); + return resolve({ fixes }); } exports.getQuickFixes = getQuickFixes; function applyQuickFix(query) { projectCache_1.consistentPath(query); - var fix = quickFixRegistry_1.allQuickFixes.filter(function (x) { return x.key == query.key; })[0]; + var fix = quickFixRegistry_1.allQuickFixes.filter(x => x.key == query.key)[0]; var info = getInfoForQuickFixAnalysis(query); var res = fix.provideFix(info); var refactorings = qf.getRefactoringsByFilePath(res); - return resolve({ refactorings: refactorings }); + return resolve({ refactorings }); } exports.applyQuickFix = applyQuickFix; -var building_1 = require("./modules/building"); +const building_1 = require("./modules/building"); function getOutput(query) { projectCache_1.consistentPath(query); var project = projectCache_1.getOrCreateProject(query.filePath); @@ -588,7 +646,7 @@ function getOutputJs(query) { projectCache_1.consistentPath(query); var project = projectCache_1.getOrCreateProject(query.filePath); var output = building_1.getRawOutput(project, query.filePath); - var jsFile = output.outputFiles.filter(function (x) { return path.extname(x.name) == ".js" || path.extname(x.name) == ".jsx"; })[0]; + var jsFile = output.outputFiles.filter(x => path.extname(x.name) == ".js" || path.extname(x.name) == ".jsx")[0]; if (!jsFile || output.emitSkipped) { return resolve({}); } @@ -609,29 +667,35 @@ function getOutputJsStatus(query) { } return resolve({ emitDiffers: true }); } - var jsFile = output.outputFiles.filter(function (x) { return path.extname(x.name) == ".js"; })[0]; + var jsFile = output.outputFiles.filter(x => path.extname(x.name) == ".js")[0]; if (!jsFile) { return resolve({ emitDiffers: false }); } else { var emitDiffers = !fs.existsSync(jsFile.name) || fs.readFileSync(jsFile.name).toString() !== jsFile.text; - return resolve({ emitDiffers: emitDiffers }); + return resolve({ emitDiffers }); } } exports.getOutputJsStatus = getOutputJsStatus; +/** + * Reset all that we know about the file system + */ function softReset(query) { projectCache_1.resetCache(query); return resolve({}); } exports.softReset = softReset; -var moveFiles = require("./modules/moveFiles"); +/** + * Get rename files refactorings + */ +const moveFiles = require("./modules/moveFiles"); function getRenameFilesRefactorings(query) { query.oldPath = fsu.consistentPath(query.oldPath); query.newPath = fsu.consistentPath(query.newPath); var project = projectCache_1.getOrCreateProject(query.oldPath); var res = moveFiles.getRenameFilesRefactorings(project.languageService.getProgram(), query.oldPath, query.newPath); var refactorings = qf.getRefactoringsByFilePath(res); - return resolve({ refactorings: refactorings }); + return resolve({ refactorings }); } exports.getRenameFilesRefactorings = getRenameFilesRefactorings; function createProject(query) { @@ -644,23 +708,30 @@ exports.createProject = createProject; function toggleBreakpoint(query) { projectCache_1.consistentPath(query); var project = projectCache_1.getOrCreateProject(query.filePath); - var program = project.languageService.getProgram(); - var sourceFile = program.getSourceFile(query.filePath); - var sourceFileText = sourceFile.getFullText(); - var positionNode = ts.getTokenAtPosition(sourceFile, query.position); - var refactoring; + // Get the node at the current location. + let program = project.languageService.getProgram(); + let sourceFile = program.getSourceFile(query.filePath); + let sourceFileText = sourceFile.getFullText(); + let positionNode = ts.getTokenAtPosition(sourceFile, query.position); + let refactoring; + // Because we add a debugger *before* the current token + // ... just preemptively check the previous token to see if *that* is a debugger keyword by any chance if (positionNode.kind != ts.SyntaxKind.DebuggerKeyword && positionNode.getFullStart() > 0) { - var previousNode = ts.getTokenAtPosition(sourceFile, positionNode.getFullStart() - 1); + let previousNode = ts.getTokenAtPosition(sourceFile, positionNode.getFullStart() - 1); + // Note: the previous node might be `debugger` if (previousNode.kind == ts.SyntaxKind.DebuggerStatement) { positionNode = previousNode; } + // Or `debugger;` (previous node would be `;` but parent is the right one) if (previousNode.parent && previousNode.parent.kind == ts.SyntaxKind.DebuggerStatement) { positionNode = previousNode.parent; } } + // If it is a debugger keyword ... remove it if (positionNode.kind == ts.SyntaxKind.DebuggerKeyword || positionNode.kind == ts.SyntaxKind.DebuggerStatement) { - var start = positionNode.getFullStart(); - var end = start + positionNode.getFullWidth(); + let start = positionNode.getFullStart(); + let end = start + positionNode.getFullWidth(); + // also get trailing semicolons while (end < sourceFileText.length && sourceFileText[end] == ';') { end = end + 1; } @@ -674,7 +745,7 @@ function toggleBreakpoint(query) { }; } else { - var toInsert = 'debugger;'; + let toInsert = 'debugger;'; refactoring = { filePath: query.filePath, span: { @@ -685,6 +756,6 @@ function toggleBreakpoint(query) { }; } var refactorings = qf.getRefactoringsByFilePath(refactoring ? [refactoring] : []); - return resolve({ refactorings: refactorings }); + return resolve({ refactorings }); } exports.toggleBreakpoint = toggleBreakpoint; diff --git a/dist/main/lang/transformers/implementations/nullTransformer.js b/dist/main/lang/transformers/implementations/nullTransformer.js deleted file mode 100644 index e35b530cd..000000000 --- a/dist/main/lang/transformers/implementations/nullTransformer.js +++ /dev/null @@ -1,13 +0,0 @@ -"use strict"; -var transformerRegistry_1 = require("../transformerRegistry"); -var NullTransformer = (function () { - function NullTransformer() { - this.name = "null"; - } - NullTransformer.prototype.transform = function (code) { - return { code: code }; - }; - return NullTransformer; -}()); -exports.NullTransformer = NullTransformer; -transformerRegistry_1.add(new NullTransformer()); diff --git a/dist/main/lang/transformers/transformer.js b/dist/main/lang/transformers/transformer.js deleted file mode 100644 index 47313d684..000000000 --- a/dist/main/lang/transformers/transformer.js +++ /dev/null @@ -1,39 +0,0 @@ -"use strict"; -var path = require("path"); -function isTransformerFile(filePath) { - var ext = path.extname(filePath); - return ext == '.tst'; -} -exports.isTransformerFile = isTransformerFile; -function getPseudoFilePath(filePath) { - if (isTransformerFile(filePath)) { - return getPseudoTsFile(filePath); - } - return filePath; -} -exports.getPseudoFilePath = getPseudoFilePath; -function getPseudoTsFile(filePath) { - return filePath + '.ts'; -} -function getTransformerFile(filePath) { - if (endsWith(filePath, '.tst.ts')) { - filePath = removeExt(filePath); - } - return filePath; -} -exports.getTransformerFile = getTransformerFile; -function isRawFile(filePath) { - return endsWith(filePath, ".raw.ts"); -} -exports.isRawFile = isRawFile; -function isPseudoFile(filePath) { - var ext = path.extname(filePath); - return endsWith(filePath, ".tst.ts"); -} -exports.isPseudoFile = isPseudoFile; -function endsWith(str, suffix) { - return str && str.indexOf(suffix, str.length - suffix.length) !== -1; -} -function removeExt(filePath) { - return filePath && filePath.substr(0, filePath.lastIndexOf('.')); -} diff --git a/dist/main/lang/transformers/transformerRegistry.js b/dist/main/lang/transformers/transformerRegistry.js deleted file mode 100644 index 896ba9da6..000000000 --- a/dist/main/lang/transformers/transformerRegistry.js +++ /dev/null @@ -1,37 +0,0 @@ -"use strict"; -var allTransformers = []; -function add(transformer) { - transformer.regex = (new RegExp("transform:" + transformer.name + "{[.\\s]*}transform:" + transformer.name, 'g')); - allTransformers.push(transformer); -} -exports.add = add; -function getNames() { - return allTransformers.map(function (at) { return at.name; }); -} -exports.getNames = getNames; -function getRegexes() { - return allTransformers.map(function (at) { return at.regex; }); -} -exports.getRegexes = getRegexes; -var transformFinderRegex = /transform:(.*){/g; -var transformEndFinderRegexGenerator = function (name) { return new RegExp("}transform:" + name); }; -function getInitialTransformation(code) { - var transforms = []; - return { transforms: transforms }; -} -exports.getInitialTransformation = getInitialTransformation; -function transform(name, code) { - var transformer = allTransformers.filter(function (at) { return at.name == name; })[0]; - if (!transformer) { - console.error('No transformer registered with name: ', name); - return { code: '' }; - } - return transformer.transform(code); -} -exports.transform = transform; -var glob = require('glob'); -var files = glob.sync('./implementations/*.js', { - nodir: true, - cwd: __dirname -}); -files = files.map(function (f) { return require(f); }); diff --git a/dist/main/lang/typescriptServices.js b/dist/main/lang/typescriptServices.js deleted file mode 100644 index 6cfc41d7b..000000000 --- a/dist/main/lang/typescriptServices.js +++ /dev/null @@ -1,6 +0,0 @@ -"use strict"; -exports.typescriptServices = ''; -function setTypescriptServices(path) { - exports.typescriptServices = path; -} -exports.setTypescriptServices = setTypescriptServices; diff --git a/dist/main/lang/utils.js b/dist/main/lang/utils.js index c63a10752..0245a3ef0 100644 --- a/dist/main/lang/utils.js +++ b/dist/main/lang/utils.js @@ -1,200 +1,69 @@ +// Copyright 2013-2014 François de Campredon +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. 'use strict'; -var path = require("path"); +Object.defineProperty(exports, "__esModule", { value: true }); +const path = require("path"); function mapValues(map) { - return Object.keys(map).reduce(function (result, key) { + return Object.keys(map).reduce((result, key) => { result.push(map[key]); return result; }, []); } exports.mapValues = mapValues; -function assign(target) { - var items = []; - for (var _i = 1; _i < arguments.length; _i++) { - items[_i - 1] = arguments[_i]; - } +/** + * assign all properties of a list of object to an object + * @param target the object that will receive properties + * @param items items which properties will be assigned to a target + */ +function assign(target, ...items) { return items.reduce(function (target, source) { - return Object.keys(source).reduce(function (target, key) { + return Object.keys(source).reduce((target, key) => { target[key] = source[key]; return target; }, target); }, target); } exports.assign = assign; +/** + * clone an object (shallow) + * @param target the object to clone + */ function clone(target) { return assign(Array.isArray(target) ? [] : {}, target); } exports.clone = clone; +/** + * Create a quick lookup map from list + */ function createMap(arr) { - return arr.reduce(function (result, key) { + return arr.reduce((result, key) => { result[key] = true; return result; }, {}); } exports.createMap = createMap; +/** + * browserify path.resolve is buggy on windows + */ function pathResolve(from, to) { var result = path.resolve(from, to); var index = result.indexOf(from[0]); return result.slice(index); } exports.pathResolve = pathResolve; -var Signal = (function () { - function Signal() { - this.listeners = []; - this.priorities = []; - } - Signal.prototype.add = function (listener, priority) { - if (priority === void 0) { priority = 0; } - var index = this.listeners.indexOf(listener); - if (index !== -1) { - this.priorities[index] = priority; - return; - } - for (var i = 0, l = this.priorities.length; i < l; i++) { - if (this.priorities[i] < priority) { - this.priorities.splice(i, 0, priority); - this.listeners.splice(i, 0, listener); - return; - } - } - this.priorities.push(priority); - this.listeners.push(listener); - }; - Signal.prototype.remove = function (listener) { - var index = this.listeners.indexOf(listener); - if (index >= 0) { - this.priorities.splice(index, 1); - this.listeners.splice(index, 1); - } - }; - Signal.prototype.dispatch = function (parameter) { - var hasBeenCanceled = this.listeners.every(function (listener) { - var result = listener(parameter); - return result !== false; - }); - return hasBeenCanceled; - }; - Signal.prototype.clear = function () { - this.listeners = []; - this.priorities = []; - }; - Signal.prototype.hasListeners = function () { - return this.listeners.length > 0; - }; - return Signal; -}()); -exports.Signal = Signal; -function binarySearch(array, value) { - var low = 0; - var high = array.length - 1; - while (low <= high) { - var middle = low + ((high - low) >> 1); - var midValue = array[middle]; - if (midValue === value) { - return middle; - } - else if (midValue > value) { - high = middle - 1; - } - else { - low = middle + 1; - } - } - return ~low; -} -exports.binarySearch = binarySearch; -function selectMany(arr) { - var result = []; - for (var i = 0; i < arr.length; i++) { - for (var j = 0; j < arr[i].length; j++) { - result.push(arr[i][j]); - } - } - return result; -} -exports.selectMany = selectMany; -function pathIsRelative(str) { - if (!str.length) - return false; - return str[0] == '.' || str.substring(0, 2) == "./" || str.substring(0, 3) == "../"; -} -exports.pathIsRelative = pathIsRelative; -var Dict = (function () { - function Dict() { - this.table = Object.create(null); - } - Dict.prototype.setValue = function (key, item) { - this.table[key] = item; - }; - Dict.prototype.getValue = function (key) { return this.table[key]; }; - Dict.prototype.clearValue = function (key) { - delete this.table[key]; - }; - Dict.prototype.clearAll = function () { this.table = Object.create(null); }; - Dict.prototype.keys = function () { return Object.keys(this.table); }; - Dict.prototype.values = function () { - var array = []; - for (var key in this.table) { - array.push(this.table[key]); - } - return array; - }; - return Dict; -}()); -exports.Dict = Dict; -function delay(seconds) { - if (seconds === void 0) { seconds = 2; } - delayMilliseconds(seconds * 1000); -} -exports.delay = delay; -; -function delayMilliseconds(milliseconds) { - if (milliseconds === void 0) { milliseconds = 100; } - var d1 = new Date(); - var d2 = new Date(); - while (d2.valueOf() < d1.valueOf() + milliseconds) { - d2 = new Date(); - } -} -exports.delayMilliseconds = delayMilliseconds; -; -var now = function () { return new Date().getTime(); }; -function debounce(func, milliseconds, immediate) { - if (immediate === void 0) { immediate = false; } - var timeout, args, context, timestamp, result; - var wait = milliseconds; - var later = function () { - var last = now() - timestamp; - if (last < wait && last > 0) { - timeout = setTimeout(later, wait - last); - } - else { - timeout = null; - if (!immediate) { - result = func.apply(context, args); - if (!timeout) - context = args = null; - } - } - }; - return function () { - context = this; - args = arguments; - timestamp = now(); - var callNow = immediate && !timeout; - if (!timeout) - timeout = setTimeout(later, wait); - if (callNow) { - result = func.apply(context, args); - context = args = null; - } - return result; - }; -} -exports.debounce = debounce; -; -var punctuations = createMap([';', '{', '}', '(', ')', '.', ':', '<', '>', "'", '"']); -exports.prefixEndsInPunctuation = function (prefix) { return prefix.length && prefix.trim().length && punctuations[prefix.trim()[prefix.trim().length - 1]]; }; var nameExtractorRegex = /return (.*);/; +/** Get the name using a lambda so that you don't have magic strings */ function getName(nameLambda) { var m = nameExtractorRegex.exec(nameLambda + ""); if (m == null) @@ -203,8 +72,10 @@ function getName(nameLambda) { return access[access.length - 1]; } exports.getName = getName; +/** Sloppy but effective code to find distinct */ function distinct(arr) { var map = createMap(arr); return Object.keys(map); } exports.distinct = distinct; +//# sourceMappingURL=utils.js.map \ No newline at end of file diff --git a/dist/main/lang/utils.js.map b/dist/main/lang/utils.js.map new file mode 100644 index 000000000..075251d73 --- /dev/null +++ b/dist/main/lang/utils.js.map @@ -0,0 +1 @@ +{"version":3,"file":"utils.js","sourceRoot":"","sources":["../../../lib/main/lang/utils.ts"],"names":[],"mappings":"AAAA,8CAA8C;AAC9C,EAAE;AACF,oEAAoE;AACpE,qEAAqE;AACrE,4CAA4C;AAC5C,EAAE;AACF,mDAAmD;AACnD,EAAE;AACF,wEAAwE;AACxE,sEAAsE;AACtE,6EAA6E;AAC7E,wEAAwE;AACxE,mCAAmC;AAEnC,YAAY,CAAC;;AAEb,6BAA8B;AAE9B,mBAA6B,GAA2B;IACpD,MAAM,CAAC,MAAM,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC,MAAM,CAAC,CAAC,MAAW,EAAE,GAAW;QACpD,MAAM,CAAC,IAAI,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC;QACtB,MAAM,CAAC,MAAM,CAAC;IAClB,CAAC,EAAE,EAAE,CAAC,CAAC;AACX,CAAC;AALD,8BAKC;AAED;;;;GAIG;AACH,gBAAuB,MAAW,EAAE,GAAG,KAAY;IAC/C,MAAM,CAAC,KAAK,CAAC,MAAM,CAAC,UAAS,MAAW,EAAE,MAAW;QACjD,MAAM,CAAC,MAAM,CAAC,IAAI,CAAC,MAAM,CAAC,CAAC,MAAM,CAAC,CAAC,MAAW,EAAE,GAAW;YACvD,MAAM,CAAC,GAAG,CAAC,GAAG,MAAM,CAAC,GAAG,CAAC,CAAC;YAC1B,MAAM,CAAC,MAAM,CAAC;QAClB,CAAC,EAAE,MAAM,CAAC,CAAC;IACf,CAAC,EAAE,MAAM,CAAC,CAAC;AACf,CAAC;AAPD,wBAOC;AAED;;;GAGG;AACH,eAAyB,MAAS;IAC9B,MAAM,CAAC,MAAM,CAAC,KAAK,CAAC,OAAO,CAAC,MAAM,CAAC,GAAG,EAAE,GAAG,EAAE,EAAE,MAAM,CAAC,CAAC;AAC3D,CAAC;AAFD,sBAEC;AAED;;GAEG;AACH,mBAA0B,GAAsB;IAC5C,MAAM,CAAC,GAAG,CAAC,MAAM,CAAC,CAAC,MAAqC,EAAE,GAAW;QACjE,MAAM,CAAC,GAAG,CAAC,GAAG,IAAI,CAAC;QACnB,MAAM,CAAC,MAAM,CAAC;IAClB,CAAC,EAAiC,EAAE,CAAC,CAAC;AAC1C,CAAC;AALD,8BAKC;AAGD;;GAEG;AACH,qBAA4B,IAAY,EAAE,EAAU;IAChD,IAAI,MAAM,GAAG,IAAI,CAAC,OAAO,CAAC,IAAI,EAAE,EAAE,CAAC,CAAC;IACpC,IAAI,KAAK,GAAG,MAAM,CAAC,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,CAAC;IACpC,MAAM,CAAC,MAAM,CAAC,KAAK,CAAC,KAAK,CAAC,CAAC;AAC/B,CAAC;AAJD,kCAIC;AAyCD,IAAI,kBAAkB,GAAG,cAAc,CAAC;AACxC,uEAAuE;AACvE,iBAAwB,UAAqB;IACzC,IAAI,CAAC,GAAG,kBAAkB,CAAC,IAAI,CAAC,UAAU,GAAG,EAAE,CAAC,CAAC;IACjD,EAAE,CAAC,CAAC,CAAC,IAAI,IAAI,CAAC;QACV,MAAM,IAAI,KAAK,CAAC,2EAA2E,CAAC,CAAC;IACjG,IAAI,MAAM,GAAG,CAAC,CAAC,CAAC,CAAC,CAAC,KAAK,CAAC,GAAG,CAAC,CAAC;IAC7B,MAAM,CAAC,MAAM,CAAC,MAAM,CAAC,MAAM,GAAG,CAAC,CAAC,CAAC;AACrC,CAAC;AAND,0BAMC;AAED,iDAAiD;AACjD,kBAAyB,GAAa;IAClC,IAAI,GAAG,GAAG,SAAS,CAAC,GAAG,CAAC,CAAC;IACzB,MAAM,CAAC,MAAM,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC;AAC5B,CAAC;AAHD,4BAGC"} \ No newline at end of file diff --git a/dist/main/react/htmltotsx.js b/dist/main/react/htmltotsx.js deleted file mode 100644 index 12ed744a8..000000000 --- a/dist/main/react/htmltotsx.js +++ /dev/null @@ -1,9 +0,0 @@ -"use strict"; -var HTMLtoJSX = require("htmltojsx"); -function convert(content, indentSize) { - var indent = Array(indentSize + 1).join(' '); - var converter = new HTMLtoJSX({ indent: indent, createClass: false }); - var output = converter.convert(content); - return output; -} -exports.convert = convert; diff --git a/dist/main/tsconfig/dts-generator.js b/dist/main/tsconfig/dts-generator.js deleted file mode 100644 index 18abcab71..000000000 --- a/dist/main/tsconfig/dts-generator.js +++ /dev/null @@ -1,172 +0,0 @@ -"use strict"; -var pathUtil = require("path"); -var os = require("os"); -var fs = require("fs"); -var mkdirp = require("mkdirp"); -function consistentPath(filePath) { - return filePath.split('\\').join('/'); -} -function getError(diagnostics) { - var message = 'Declaration generation failed'; - diagnostics.forEach(function (diagnostic) { - var position = diagnostic.file.getLineAndCharacterOfPosition(diagnostic.start); - message += - "\n" + diagnostic.file.fileName + "(" + (position.line + 1) + "," + (position.character + 1) + "): " + - ("error TS" + diagnostic.code + ": " + diagnostic.messageText); - }); - var error = new Error(message); - error.name = 'EmitterError'; - return error; -} -function makeRelativePath(relativeFolder, filePath) { - var relativePath = pathUtil.relative(relativeFolder, filePath).split('\\').join('/'); - if (relativePath[0] !== '.') { - relativePath = './' + relativePath; - } - return relativePath; -} -function getFilenames(baseDir, files) { - return files.map(function (filename) { - var resolvedFilename = pathUtil.resolve(filename); - if (resolvedFilename.indexOf(baseDir) === 0) { - return resolvedFilename; - } - return pathUtil.resolve(baseDir, filename); - }); -} -function processTree(sourceFile, replacer) { - var code = ''; - var cursorPosition = 0; - function skip(node) { - cursorPosition = node.end; - } - function readThrough(node) { - code += sourceFile.text.slice(cursorPosition, node.pos); - cursorPosition = node.pos; - } - function visit(node) { - readThrough(node); - var replacement = replacer(node); - if (replacement != null) { - code += replacement; - skip(node); - } - else { - ts.forEachChild(node, visit); - } - } - visit(sourceFile); - code += sourceFile.text.slice(cursorPosition); - return code; -} -function generate(options, sendMessage) { - if (sendMessage === void 0) { sendMessage = function () { }; } - var baseDir = pathUtil.resolve(options.baseDir); - var eol = options.eol || os.EOL; - var nonEmptyLineStart = new RegExp(eol + '(?!' + eol + '|$)', 'g'); - var indent = options.indent === undefined ? '\t' : options.indent; - var target = options.target || ts.ScriptTarget.Latest; - var compilerOptions = { - declaration: true, - module: ts.ModuleKind.CommonJS, - target: target - }; - if (options.outDir) { - compilerOptions.outDir = options.outDir; - } - var filenames = getFilenames(baseDir, options.files); - var excludesMap = {}; - options.excludes && options.excludes.forEach(function (filename) { - excludesMap[consistentPath(pathUtil.resolve(baseDir, filename))] = true; - }); - var externsMap = {}; - options.externs && options.externs.forEach(function (filename) { - externsMap[consistentPath(pathUtil.resolve(baseDir, filename))] = true; - }); - mkdirp.sync(pathUtil.dirname(options.out)); - var output = fs.createWriteStream(options.out, { mode: parseInt('644', 8) }); - var host = ts.createCompilerHost(compilerOptions); - var program = ts.createProgram(filenames, compilerOptions, host); - var checker = ts.createTypeChecker(program, true); - function writeFile(filename, data, writeByteOrderMark) { - if (filename.slice(-5) !== '.d.ts') { - return; - } - writeDeclaration(ts.createSourceFile(filename, data, target, true)); - } - return new Promise(function (resolve, reject) { - output.on('close', function () { resolve(undefined); }); - output.on('error', reject); - if (options.externs) { - var relativeRoot_1 = pathUtil.dirname(options.out); - options.externs.forEach(function (path) { - sendMessage("Writing external dependency " + path); - output.write("/// " + eol); - }); - } - program.getSourceFiles().some(function (sourceFile) { - if (pathUtil.normalize(sourceFile.fileName).indexOf(baseDir) !== 0) { - return; - } - if (excludesMap[sourceFile.fileName]) { - return; - } - if (externsMap[sourceFile.fileName]) { - return; - } - sendMessage("Processing " + sourceFile.fileName); - if (sourceFile.fileName.slice(-5) === '.d.ts') { - writeDeclaration(sourceFile); - return; - } - var emitOutput = program.emit(sourceFile, writeFile); - if (emitOutput.emitSkipped) { - reject(getError(emitOutput.diagnostics - .concat(program.getSemanticDiagnostics(sourceFile)) - .concat(program.getSyntacticDiagnostics(sourceFile)) - .concat(program.getDeclarationDiagnostics(sourceFile)))); - return true; - } - }); - if (options.main) { - output.write("declare module '" + options.name + "' {" + eol + indent); - output.write("import main = require('" + options.main + "');" + eol + indent); - output.write('export = main;' + eol); - output.write('}' + eol); - sendMessage("Aliased main module " + options.name + " to " + options.main); - } - output.end(); - }); - function writeDeclaration(declarationFile) { - var filename = declarationFile.fileName; - var sourceModuleId = options.name + consistentPath(filename.slice(baseDir.length, -5)); - if (declarationFile.externalModuleIndicator) { - output.write('declare module \'' + sourceModuleId + '\' {' + eol + indent); - var content = processTree(declarationFile, function (node) { - if (node.kind === ts.SyntaxKind.ExternalModuleReference) { - var expression = node.expression; - if (expression.text.charAt(0) === '.') { - return ' require(\'' + pathUtil.join(pathUtil.dirname(sourceModuleId), expression.text) + '\')'; - } - } - else if (node.kind === ts.SyntaxKind.DeclareKeyword) { - return ''; - } - else if (node.kind === ts.SyntaxKind.StringLiteral && - (node.parent.kind === ts.SyntaxKind.ExportDeclaration - || node.parent.kind === ts.SyntaxKind.ImportDeclaration)) { - var text = node.text; - if (text.charAt(0) === '.') { - return " '" + consistentPath(pathUtil.join(pathUtil.dirname(sourceModuleId), text)) + "'"; - } - } - }); - output.write(content.replace(nonEmptyLineStart, '$&' + indent)); - output.write(eol + '}' + eol); - } - else { - output.write(declarationFile.text); - } - } -} -exports.generate = generate; diff --git a/dist/main/tsconfig/formatting.js b/dist/main/tsconfig/formatting.js index b6ae6e796..99a67dfe4 100644 --- a/dist/main/tsconfig/formatting.js +++ b/dist/main/tsconfig/formatting.js @@ -1,72 +1,33 @@ "use strict"; -var os = require("os"); +Object.defineProperty(exports, "__esModule", { value: true }); +/** + * Maintainance: + * When a new option is added add it to: + * - the FormatCodeOptions interface + * - the defaultFormatCodeOptions function + * - the makeFormatCodeOptions function + */ +const os_1 = require("os"); function defaultFormatCodeOptions() { return { - IndentSize: 4, - TabSize: 4, - NewLineCharacter: os.EOL, - ConvertTabsToSpaces: true, - IndentStyle: ts.IndentStyle.Smart, - InsertSpaceAfterCommaDelimiter: true, - InsertSpaceAfterSemicolonInForStatements: true, - InsertSpaceBeforeAndAfterBinaryOperators: true, - InsertSpaceAfterKeywordsInControlFlowStatements: true, - InsertSpaceAfterFunctionKeywordForAnonymousFunctions: false, - InsertSpaceAfterOpeningAndBeforeClosingNonemptyParenthesis: false, - InsertSpaceAfterOpeningAndBeforeClosingNonemptyBrackets: false, - InsertSpaceAfterOpeningAndBeforeClosingTemplateStringBraces: false, - PlaceOpenBraceOnNewLineForFunctions: false, - PlaceOpenBraceOnNewLineForControlBlocks: false, + baseIndentSize: 4, + indentSize: 4, + tabSize: 4, + newLineCharacter: os_1.EOL, + convertTabsToSpaces: true, + indentStyle: "Smart", + insertSpaceAfterCommaDelimiter: true, + insertSpaceAfterSemicolonInForStatements: true, + insertSpaceBeforeAndAfterBinaryOperators: true, + insertSpaceAfterKeywordsInControlFlowStatements: true, + insertSpaceAfterFunctionKeywordForAnonymousFunctions: false, + insertSpaceAfterOpeningAndBeforeClosingNonemptyParenthesis: false, + insertSpaceAfterOpeningAndBeforeClosingNonemptyBrackets: false, + insertSpaceAfterOpeningAndBeforeClosingTemplateStringBraces: false, + insertSpaceAfterOpeningAndBeforeClosingJsxExpressionBraces: false, + placeOpenBraceOnNewLineForFunctions: false, + placeOpenBraceOnNewLineForControlBlocks: false, }; } exports.defaultFormatCodeOptions = defaultFormatCodeOptions; -function makeFormatCodeOptions(config) { - var options = defaultFormatCodeOptions(); - if (!config) { - return options; - } - if (typeof config.insertSpaceAfterCommaDelimiter === "boolean") { - options.InsertSpaceAfterCommaDelimiter = config.insertSpaceAfterCommaDelimiter; - } - if (typeof config.insertSpaceAfterSemicolonInForStatements === "boolean") { - options.InsertSpaceAfterSemicolonInForStatements = config.insertSpaceAfterSemicolonInForStatements; - } - if (typeof config.insertSpaceBeforeAndAfterBinaryOperators === "boolean") { - options.InsertSpaceBeforeAndAfterBinaryOperators = config.insertSpaceBeforeAndAfterBinaryOperators; - } - if (typeof config.insertSpaceAfterKeywordsInControlFlowStatements === "boolean") { - options.InsertSpaceAfterKeywordsInControlFlowStatements = config.insertSpaceAfterKeywordsInControlFlowStatements; - } - if (typeof config.insertSpaceAfterFunctionKeywordForAnonymousFunctions === "boolean") { - options.InsertSpaceAfterFunctionKeywordForAnonymousFunctions = config.insertSpaceAfterFunctionKeywordForAnonymousFunctions; - } - if (typeof config.insertSpaceAfterOpeningAndBeforeClosingNonemptyParenthesis === "boolean") { - options.InsertSpaceAfterOpeningAndBeforeClosingNonemptyParenthesis = config.insertSpaceAfterOpeningAndBeforeClosingNonemptyParenthesis; - } - if (typeof config.insertSpaceAfterOpeningAndBeforeClosingNonemptyBrackets === "boolean") { - options.InsertSpaceAfterOpeningAndBeforeClosingNonemptyBrackets = config.insertSpaceAfterOpeningAndBeforeClosingNonemptyBrackets; - } - if (typeof config.insertSpaceAfterOpeningAndBeforeClosingTemplateStringBraces === "boolean") { - options.InsertSpaceAfterOpeningAndBeforeClosingTemplateStringBraces = config.insertSpaceAfterOpeningAndBeforeClosingTemplateStringBraces; - } - if (typeof config.placeOpenBraceOnNewLineForFunctions === "boolean") { - options.PlaceOpenBraceOnNewLineForFunctions = config.placeOpenBraceOnNewLineForFunctions; - } - if (typeof config.placeOpenBraceOnNewLineForControlBlocks === "boolean") { - options.PlaceOpenBraceOnNewLineForControlBlocks = config.placeOpenBraceOnNewLineForControlBlocks; - } - if (typeof config.indentSize === "number") { - options.IndentSize = config.indentSize; - } - if (typeof config.tabSize === "number") { - options.TabSize = config.tabSize; - } - if (typeof config.newLineCharacter === "string") { - options.NewLineCharacter = config.newLineCharacter; - } - if (typeof config.convertTabsToSpaces === "boolean") { - options.ConvertTabsToSpaces = config.convertTabsToSpaces; - } - return options; -} -exports.makeFormatCodeOptions = makeFormatCodeOptions; +//# sourceMappingURL=formatting.js.map \ No newline at end of file diff --git a/dist/main/tsconfig/formatting.js.map b/dist/main/tsconfig/formatting.js.map new file mode 100644 index 000000000..7d7c1e322 --- /dev/null +++ b/dist/main/tsconfig/formatting.js.map @@ -0,0 +1 @@ +{"version":3,"file":"formatting.js","sourceRoot":"","sources":["../../../lib/main/tsconfig/formatting.ts"],"names":[],"mappings":";;AAAA;;;;;;GAMG;AACH,2BAAsB;AAGtB;IACI,MAAM,CAAC;QACH,cAAc,EAAE,CAAC;QACjB,UAAU,EAAE,CAAC;QACb,OAAO,EAAE,CAAC;QACV,gBAAgB,EAAE,QAAG;QACrB,mBAAmB,EAAE,IAAI;QACzB,WAAW,EAAE,OAAO;QACpB,8BAA8B,EAAE,IAAI;QACpC,wCAAwC,EAAE,IAAI;QAC9C,wCAAwC,EAAE,IAAI;QAC9C,+CAA+C,EAAE,IAAI;QACrD,oDAAoD,EAAE,KAAK;QAC3D,0DAA0D,EAAE,KAAK;QACjE,uDAAuD,EAAE,KAAK;QAC9D,2DAA2D,EAAE,KAAK;QAClE,0DAA0D,EAAE,KAAK;QACjE,mCAAmC,EAAE,KAAK;QAC1C,uCAAuC,EAAE,KAAK;KACjD,CAAC;AACN,CAAC;AApBD,4DAoBC"} \ No newline at end of file diff --git a/dist/main/tsconfig/simpleValidator.js b/dist/main/tsconfig/simpleValidator.js deleted file mode 100644 index 017f20e4b..000000000 --- a/dist/main/tsconfig/simpleValidator.js +++ /dev/null @@ -1,65 +0,0 @@ -"use strict"; -exports.types = { - string: 'string', - boolean: 'boolean', - number: 'number', - object: 'object', - array: 'array' -}; -var SimpleValidator = (function () { - function SimpleValidator(validationInfo) { - var _this = this; - this.validationInfo = validationInfo; - this.potentialLowerCaseMatch = {}; - Object.keys(validationInfo).forEach(function (k) { return _this.potentialLowerCaseMatch[k.toLowerCase()] = k; }); - } - SimpleValidator.prototype.validate = function (config) { - var _this = this; - var keys = Object.keys(config); - var errors = { invalidValues: [], extraKeys: [], errorMessage: '' }; - keys.forEach(function (k) { - if (!_this.validationInfo[k]) { - if (_this.potentialLowerCaseMatch[k]) { - errors.extraKeys.push("Key: '" + k + "' is a potential lower case match for '" + _this.potentialLowerCaseMatch[k] + "'. Fix the casing."); - } - else { - errors.extraKeys.push("Unknown Option: " + k); - } - } - else { - var validationInfo = _this.validationInfo[k]; - var value = config[k]; - if (validationInfo.type && validationInfo.type === 'array') { - if (!Array.isArray(value)) { - errors.invalidValues.push("Key: '" + k + "' has an invalid type: " + typeof value); - } - } - else { - if (validationInfo.validValues && validationInfo.validValues.length) { - var validValues = validationInfo.validValues; - if (!validValues.some(function (valid) { return valid.toLowerCase() === value.toLowerCase(); })) { - errors.invalidValues.push("Key: '" + k + "' has an invalid value: " + value); - } - } - if (validationInfo.type && typeof value !== validationInfo.type) { - errors.invalidValues.push("Key: '" + k + "' has an invalid type: " + typeof value); - } - } - } - }); - var total = errors.invalidValues.concat(errors.extraKeys); - if (total.length) { - errors.errorMessage = total.join("\n"); - } - return errors; - }; - return SimpleValidator; -}()); -exports.SimpleValidator = SimpleValidator; -function createMap(arr) { - return arr.reduce(function (result, key) { - result[key] = true; - return result; - }, {}); -} -exports.createMap = createMap; diff --git a/dist/main/tsconfig/tsconfig.js b/dist/main/tsconfig/tsconfig.js deleted file mode 100644 index d3a2aeb8f..000000000 --- a/dist/main/tsconfig/tsconfig.js +++ /dev/null @@ -1,584 +0,0 @@ -"use strict"; -var fsu = require("../utils/fsUtil"); -var simpleValidator = require("./simpleValidator"); -var types = simpleValidator.types; -var compilerOptionsValidation = { - allowJs: { type: types.boolean }, - allowNonTsExtensions: { type: types.boolean }, - allowSyntheticDefaultImports: { type: types.boolean }, - allowUnreachableCode: { type: types.boolean }, - allowUnusedLabels: { type: types.boolean }, - alwaysStrict: { type: types.boolean }, - baseUrl: { type: types.string }, - charset: { type: types.string }, - codepage: { type: types.number }, - declaration: { type: types.boolean }, - declarationDir: { type: types.string }, - diagnostics: { type: types.boolean }, - emitBOM: { type: types.boolean }, - emitDecoratorMetadata: { type: types.boolean }, - experimentalAsyncFunctions: { type: types.boolean }, - experimentalDecorators: { type: types.boolean }, - forceConsistentCasingInFileNames: { type: types.boolean }, - help: { type: types.boolean }, - importHelpers: { type: types.boolean }, - inlineSourceMap: { type: types.boolean }, - inlineSources: { type: types.boolean }, - isolatedModules: { type: types.boolean }, - jsx: { type: types.string, validValues: ['preserve', 'react'] }, - jsxFactory: { type: types.string }, - lib: { type: types.array }, - listFiles: { type: types.boolean }, - locals: { type: types.string }, - mapRoot: { type: types.string }, - module: { type: types.string, validValues: ['commonjs', 'amd', 'system', 'umd', 'es6', 'es2015', 'none'] }, - moduleResolution: { type: types.string, validValues: ['classic', 'node'] }, - newLine: { type: types.string }, - noEmit: { type: types.boolean }, - noEmitHelpers: { type: types.boolean }, - noEmitOnError: { type: types.boolean }, - noErrorTruncation: { type: types.boolean }, - noFallthroughCasesInSwitch: { type: types.boolean }, - noImplicitAny: { type: types.boolean }, - noImplicitReturns: { type: types.boolean }, - noImplicitThis: { type: types.boolean }, - noImplicitUseStrict: { type: types.boolean }, - noLib: { type: types.boolean }, - noLibCheck: { type: types.boolean }, - noResolve: { type: types.boolean }, - noUnusedLocals: { type: types.boolean }, - noUnusedParameters: { type: types.boolean }, - out: { type: types.string }, - outDir: { type: types.string }, - outFile: { type: types.string }, - paths: { type: types.object }, - preserveConstEnums: { type: types.boolean }, - pretty: { type: types.boolean }, - project: { type: types.string }, - reactNamespace: { type: types.string }, - removeComments: { type: types.boolean }, - rootDir: { type: types.string }, - rootDirs: { type: types.object }, - skipDefaultLibCheck: { type: types.boolean }, - skipLibCheck: { type: types.boolean }, - sourceMap: { type: types.boolean }, - sourceRoot: { type: types.string }, - strictNullChecks: { type: types.boolean }, - stripInternal: { type: types.boolean }, - suppressExcessPropertyErrors: { type: types.boolean }, - suppressImplicitAnyIndexErrors: { type: types.boolean }, - target: { type: types.string, validValues: ['es3', 'es5', 'es6', 'es2015', 'es2016', 'es2017', 'esnext'] }, - typeRoots: { type: types.array }, - types: { type: types.array }, - version: { type: types.boolean }, - watch: { type: types.boolean }, -}; -var validator = new simpleValidator.SimpleValidator(compilerOptionsValidation); -exports.errors = { - GET_PROJECT_INVALID_PATH: 'The path used to query for tsconfig.json does not exist', - GET_PROJECT_NO_PROJECT_FOUND: 'No Project Found', - GET_PROJECT_FAILED_TO_OPEN_PROJECT_FILE: 'Failed to fs.readFileSync the project file', - GET_PROJECT_JSON_PARSE_FAILED: 'Failed to JSON.parse the project file', - GET_PROJECT_GLOB_EXPAND_FAILED: 'Failed to expand filesGlob in the project file', - GET_PROJECT_PROJECT_FILE_INVALID_OPTIONS: 'Project file contains invalid options', - CREATE_FILE_MUST_EXIST: 'The Typescript file must exist on disk in order to create a project', - CREATE_PROJECT_ALREADY_EXISTS: 'Project file already exists', -}; -function errorWithDetails(error, details) { - error.details = details; - return error; -} -var fs = require("fs"); -var path = require("path"); -var tsconfig = require("tsconfig"); -var os = require("os"); -var detectIndent = require("detect-indent"); -var detectNewline = require("detect-newline"); -var formatting = require("./formatting"); -var projectFileName = 'tsconfig.json'; -var defaultFilesGlob = [ - "**/*.ts", - "**/*.tsx", - "!node_modules/**", -]; -var invisibleFilesGlob = '{**/*.ts,**/*.tsx}'; -exports.defaults = { - target: ts.ScriptTarget.ES5, - module: ts.ModuleKind.CommonJS, - moduleResolution: ts.ModuleResolutionKind.NodeJs, - isolatedModules: false, - jsx: ts.JsxEmit.React, - experimentalDecorators: true, - emitDecoratorMetadata: true, - declaration: false, - noImplicitAny: false, - noImplicitUseStrict: false, - removeComments: true, - noLib: false, - preserveConstEnums: true, - suppressImplicitAnyIndexErrors: true -}; -var typescriptEnumMap = { - target: { - 'es3': ts.ScriptTarget.ES3, - 'es5': ts.ScriptTarget.ES5, - 'es6': ts.ScriptTarget.ES2015, - 'es2015': ts.ScriptTarget.ES2015, - 'es2016': ts.ScriptTarget.ES2016, - 'es2017': ts.ScriptTarget.ES2017, - 'esnext': ts.ScriptTarget.Latest, - }, - module: { - 'none': ts.ModuleKind.None, - 'commonjs': ts.ModuleKind.CommonJS, - 'amd': ts.ModuleKind.AMD, - 'umd': ts.ModuleKind.UMD, - 'system': ts.ModuleKind.System, - 'es6': ts.ModuleKind.ES2015, - 'es2015': ts.ModuleKind.ES2015, - }, - moduleResolution: { - 'node': ts.ModuleResolutionKind.NodeJs, - 'classic': ts.ModuleResolutionKind.Classic - }, - jsx: { - 'preserve': ts.JsxEmit.Preserve, - 'react': ts.JsxEmit.React - }, - newLine: { - 'CRLF': ts.NewLineKind.CarriageReturnLineFeed, - 'LF': ts.NewLineKind.LineFeed - } -}; -var jsonEnumMap = {}; -Object.keys(typescriptEnumMap).forEach(function (name) { - jsonEnumMap[name] = reverseKeysAndValues(typescriptEnumMap[name]); -}); -function mixin(target, source) { - for (var key in source) { - target[key] = source[key]; - } - return target; -} -function rawToTsCompilerOptions(jsonOptions, projectDir) { - var compilerOptions = mixin({}, exports.defaults); - for (var key in jsonOptions) { - if (typescriptEnumMap[key]) { - var name_1 = jsonOptions[key]; - var map = typescriptEnumMap[key]; - compilerOptions[key] = map[name_1.toLowerCase()] || map[name_1.toUpperCase()]; - } - else { - compilerOptions[key] = jsonOptions[key]; - } - } - if (compilerOptions.outDir !== undefined) { - compilerOptions.outDir = path.resolve(projectDir, compilerOptions.outDir); - } - if (compilerOptions.rootDir !== undefined) { - compilerOptions.rootDir = path.resolve(projectDir, compilerOptions.rootDir); - } - if (compilerOptions.out !== undefined) { - compilerOptions.outFile = path.resolve(projectDir, compilerOptions.out); - } - if (compilerOptions.outFile !== undefined) { - compilerOptions.outFile = path.resolve(projectDir, compilerOptions.outFile); - } - if (compilerOptions.baseUrl !== undefined) { - compilerOptions.baseUrl = path.resolve(projectDir, compilerOptions.baseUrl); - } - if (compilerOptions.rootDirs !== undefined && Array.isArray(compilerOptions.rootDirs)) { - compilerOptions.rootDirs = compilerOptions.rootDirs.map(function (dir) { - return path.resolve(projectDir, dir); - }); - } - return compilerOptions; -} -function tsToRawCompilerOptions(compilerOptions) { - var jsonOptions = mixin({}, compilerOptions); - Object.keys(compilerOptions).forEach(function (key) { - if (jsonEnumMap[key] && compilerOptions[key]) { - var value = compilerOptions[key]; - jsonOptions[key] = jsonEnumMap[key][value]; - } - }); - return jsonOptions; -} -function getDefaultInMemoryProject(srcFile) { - var dir = fs.lstatSync(srcFile).isDirectory() ? srcFile : path.dirname(srcFile); - var files = [srcFile]; - var typings = getDefinitionsForNodeModules(dir, files); - files = increaseProjectForReferenceAndImports(files); - files = uniq(files.map(fsu.consistentPath)); - var project = { - compilerOptions: exports.defaults, - files: files, - typings: typings.ours.concat(typings.implicit), - formatCodeOptions: formatting.defaultFormatCodeOptions(), - compileOnSave: true, - buildOnSave: false, - scripts: {}, - atom: { rewriteTsconfig: false, formatOnSave: false }, - }; - return { - projectFileDirectory: dir, - projectFilePath: dir + '/' + projectFileName, - project: project, - inMemory: true - }; -} -exports.getDefaultInMemoryProject = getDefaultInMemoryProject; -function getProjectSync(pathOrSrcFile) { - if (!fs.existsSync(pathOrSrcFile)) { - throw new Error(exports.errors.GET_PROJECT_INVALID_PATH); - } - var dir = fs.lstatSync(pathOrSrcFile).isDirectory() ? pathOrSrcFile : path.dirname(pathOrSrcFile); - var projectFile = tsconfig.resolveSync(dir); - if (!projectFile) { - throw errorWithDetails(new Error(exports.errors.GET_PROJECT_NO_PROJECT_FOUND), { projectFilePath: fsu.consistentPath(pathOrSrcFile), errorMessage: 'not found' }); - } - var projectFileDirectory = path.dirname(projectFile) + path.sep; - var projectSpec; - var projectFileTextContent; - try { - projectFileTextContent = fs.readFileSync(projectFile, 'utf8'); - } - catch (ex) { - throw new Error(exports.errors.GET_PROJECT_FAILED_TO_OPEN_PROJECT_FILE); - } - try { - projectSpec = tsconfig.parseFileSync(projectFileTextContent, projectFile, { resolvePaths: false }); - } - catch (ex) { - throw errorWithDetails(new Error(exports.errors.GET_PROJECT_JSON_PARSE_FAILED), { projectFilePath: fsu.consistentPath(projectFile), error: ex.message }); - } - if (!projectSpec.atom) { - projectSpec.atom = { - rewriteTsconfig: false, - }; - } - if (projectSpec.filesGlob) { - var prettyJSONProjectSpec = prettyJSON(projectSpec, detectIndent(projectFileTextContent).indent, detectNewline(projectFileTextContent)); - if (prettyJSONProjectSpec !== projectFileTextContent && projectSpec.atom.rewriteTsconfig) { - fs.writeFileSync(projectFile, prettyJSONProjectSpec); - } - } - var pkg = null; - try { - var packagePath = travelUpTheDirectoryTreeTillYouFind(projectFileDirectory, 'package.json'); - if (packagePath) { - var packageJSONPath = getPotentiallyRelativeFile(projectFileDirectory, packagePath); - var parsedPackage = JSON.parse(fs.readFileSync(packageJSONPath).toString()); - pkg = { - main: parsedPackage.main, - name: parsedPackage.name, - directory: path.dirname(packageJSONPath), - definition: parsedPackage.typescript && parsedPackage.typescript.definition - }; - } - } - catch (ex) { - } - var project = { - compilerOptions: {}, - files: projectSpec.files.map(function (x) { return path.resolve(projectFileDirectory, x); }), - filesGlob: projectSpec.filesGlob, - formatCodeOptions: formatting.makeFormatCodeOptions(projectSpec.formatCodeOptions), - compileOnSave: projectSpec.compileOnSave == undefined ? true : projectSpec.compileOnSave, - package: pkg, - typings: [], - externalTranspiler: projectSpec.externalTranspiler == undefined ? undefined : projectSpec.externalTranspiler, - scripts: projectSpec.scripts || {}, - buildOnSave: !!projectSpec.buildOnSave, - atom: { rewriteTsconfig: false, formatOnSave: !!projectSpec.atom.formatOnSave } - }; - var validationResult = validator.validate(projectSpec.compilerOptions); - if (validationResult.errorMessage) { - throw errorWithDetails(new Error(exports.errors.GET_PROJECT_PROJECT_FILE_INVALID_OPTIONS), { projectFilePath: fsu.consistentPath(projectFile), errorMessage: validationResult.errorMessage }); - } - project.compilerOptions = rawToTsCompilerOptions(projectSpec.compilerOptions, projectFileDirectory); - project.files = increaseProjectForReferenceAndImports(project.files); - var typings = getDefinitionsForNodeModules(dir, project.files); - project.files = project.files.concat(typings.implicit); - project.typings = typings.ours.concat(typings.implicit); - project.files = project.files.concat(typings.packagejson); - project.files = uniq(project.files.map(fsu.consistentPath)); - projectFileDirectory = removeTrailingSlash(fsu.consistentPath(projectFileDirectory)); - return { - projectFileDirectory: projectFileDirectory, - projectFilePath: projectFileDirectory + '/' + projectFileName, - project: project, - inMemory: false - }; -} -exports.getProjectSync = getProjectSync; -function createProjectRootSync(srcFile, defaultOptions) { - if (!fs.existsSync(srcFile)) { - throw new Error(exports.errors.CREATE_FILE_MUST_EXIST); - } - var dir = fs.lstatSync(srcFile).isDirectory() ? srcFile : path.dirname(srcFile); - var projectFilePath = path.normalize(dir + '/' + projectFileName); - if (fs.existsSync(projectFilePath)) - throw new Error(exports.errors.CREATE_PROJECT_ALREADY_EXISTS); - var projectSpec = {}; - projectSpec.compilerOptions = tsToRawCompilerOptions(defaultOptions || exports.defaults); - projectSpec.exclude = ["node_modules", "typings/browser", "typings/browser.d.ts"]; - projectSpec.compileOnSave = true; - projectSpec.buildOnSave = false; - projectSpec.atom = { - rewriteTsconfig: false - }; - fs.writeFileSync(projectFilePath, prettyJSON(projectSpec)); - return getProjectSync(srcFile); -} -exports.createProjectRootSync = createProjectRootSync; -function increaseProjectForReferenceAndImports(files) { - var filesMap = simpleValidator.createMap(files); - var willNeedMoreAnalysis = function (file) { - if (!filesMap[file]) { - filesMap[file] = true; - files.push(file); - return true; - } - else { - return false; - } - }; - var getReferencedOrImportedFiles = function (files) { - var referenced = []; - files.forEach(function (file) { - try { - var content = fs.readFileSync(file).toString(); - } - catch (ex) { - return; - } - var preProcessedFileInfo = ts.preProcessFile(content, true), dir = path.dirname(file); - var extensions = ['.ts', '.d.ts', '.tsx']; - function getIfExists(filePathNoExt) { - for (var _i = 0, extensions_1 = extensions; _i < extensions_1.length; _i++) { - var ext = extensions_1[_i]; - if (fs.existsSync(filePathNoExt + ext)) { - return filePathNoExt + ext; - } - } - } - referenced.push(preProcessedFileInfo.referencedFiles.map(function (fileReference) { - var file = path.resolve(dir, fsu.consistentPath(fileReference.fileName)); - if (fs.existsSync(file)) { - return file; - } - return getIfExists(file); - }).filter(function (file) { return !!file; }) - .concat(preProcessedFileInfo.importedFiles - .filter(function (fileReference) { return pathIsRelative(fileReference.fileName); }) - .map(function (fileReference) { - var fileNoExt = path.resolve(dir, fileReference.fileName); - var file = getIfExists(fileNoExt); - if (!file) { - file = getIfExists(file + "/index"); - } - return file; - }).filter(function (file) { return !!file; }))); - }); - return selectMany(referenced); - }; - var more = getReferencedOrImportedFiles(files) - .filter(willNeedMoreAnalysis); - while (more.length) { - more = getReferencedOrImportedFiles(files) - .filter(willNeedMoreAnalysis); - } - return files; -} -function getDefinitionsForNodeModules(projectDir, files) { - var packagejson = []; - function versionStringToNumber(version) { - var _a = version.split('.'), maj = _a[0], min = _a[1], patch = _a[2]; - return parseInt(maj) * 1000000 + parseInt(min); - } - var typings = {}; - var ourTypings = files - .filter(function (f) { return path.basename(path.dirname(f)) == 'typings' && endsWith(f, '.d.ts') - || path.basename(path.dirname(path.dirname(f))) == 'typings' && endsWith(f, '.d.ts'); }); - ourTypings.forEach(function (f) { return typings[path.basename(f)] = { filePath: f, version: Infinity }; }); - var existing = createMap(files.map(fsu.consistentPath)); - function addAllReferencedFilesWithMaxVersion(file) { - var dir = path.dirname(file); - try { - var content = fs.readFileSync(file).toString(); - } - catch (ex) { - return; - } - var preProcessedFileInfo = ts.preProcessFile(content, true); - var files = preProcessedFileInfo.referencedFiles.map(function (fileReference) { - var file = path.resolve(dir, fileReference.fileName); - if (fs.existsSync(file)) { - return file; - } - if (fs.existsSync(file + '.d.ts')) { - return file + '.d.ts'; - } - }).filter(function (f) { return !!f; }); - files = files - .filter(function (f) { return !typings[path.basename(f)] || typings[path.basename(f)].version > Infinity; }); - files.forEach(function (f) { return typings[path.basename(f)] = { filePath: f, version: Infinity }; }); - files.forEach(function (f) { return addAllReferencedFilesWithMaxVersion(f); }); - } - try { - var node_modules = travelUpTheDirectoryTreeTillYouFind(projectDir, 'node_modules', true); - var moduleDirs = getDirs(node_modules); - for (var _i = 0, moduleDirs_1 = moduleDirs; _i < moduleDirs_1.length; _i++) { - var moduleDir = moduleDirs_1[_i]; - try { - var package_json = JSON.parse(fs.readFileSync(moduleDir + "/package.json").toString()); - packagejson.push(moduleDir + "/package.json"); - } - catch (ex) { - continue; - } - if (package_json.typescript && package_json.typescript.definition) { - var file = path.resolve(moduleDir, './', package_json.typescript.definition); - typings[path.basename(file)] = { - filePath: file, - version: Infinity - }; - addAllReferencedFilesWithMaxVersion(file); - } - } - } - catch (ex) { - if (ex.message == "not found") { - } - else { - console.error('Failed to read package.json from node_modules due to error:', ex, ex.stack); - } - } - var all = Object.keys(typings) - .map(function (typing) { return typings[typing].filePath; }) - .map(function (x) { return fsu.consistentPath(x); }); - var implicit = all - .filter(function (x) { return !existing[x]; }); - var ours = all - .filter(function (x) { return existing[x]; }); - return { implicit: implicit, ours: ours, packagejson: packagejson }; -} -function prettyJSON(object, indent, newLine) { - if (indent === void 0) { indent = 4; } - if (newLine === void 0) { newLine = os.EOL; } - var cache = []; - var value = JSON.stringify(object, function (key, value) { - if (typeof value === 'object' && value !== null) { - if (cache.indexOf(value) !== -1) { - return; - } - cache.push(value); - } - return value; - }, indent); - value = value.replace(/(?:\r\n|\r|\n)/g, newLine) + newLine; - cache = null; - return value; -} -exports.prettyJSON = prettyJSON; -function pathIsRelative(str) { - if (!str.length) - return false; - return str[0] == '.' || str.substring(0, 2) == "./" || str.substring(0, 3) == "../"; -} -exports.pathIsRelative = pathIsRelative; -function selectMany(arr) { - var result = []; - for (var i = 0; i < arr.length; i++) { - for (var j = 0; j < arr[i].length; j++) { - result.push(arr[i][j]); - } - } - return result; -} -function endsWith(str, suffix) { - return str && str.indexOf(suffix, str.length - suffix.length) !== -1; -} -exports.endsWith = endsWith; -function uniq(arr) { - var map = simpleValidator.createMap(arr); - return Object.keys(map); -} -function makeRelativePath(relativeFolder, filePath) { - var relativePath = path.relative(relativeFolder, filePath).split('\\').join('/'); - if (relativePath[0] !== '.') { - relativePath = './' + relativePath; - } - return relativePath; -} -exports.makeRelativePath = makeRelativePath; -function removeExt(filePath) { - return filePath.substr(0, filePath.lastIndexOf('.')); -} -exports.removeExt = removeExt; -function removeTrailingSlash(filePath) { - if (!filePath) - return filePath; - if (endsWith(filePath, '/')) - return filePath.substr(0, filePath.length - 1); - return filePath; -} -exports.removeTrailingSlash = removeTrailingSlash; -function travelUpTheDirectoryTreeTillYouFind(dir, fileOrDirectory, abortIfInside) { - if (abortIfInside === void 0) { abortIfInside = false; } - while (fs.existsSync(dir)) { - var potentialFile = dir + '/' + fileOrDirectory; - if (before == potentialFile) { - if (abortIfInside) { - throw new Error("not found"); - } - } - if (fs.existsSync(potentialFile)) { - return potentialFile; - } - else { - var before = dir; - dir = path.dirname(dir); - if (dir == before) - throw new Error("not found"); - } - } -} -exports.travelUpTheDirectoryTreeTillYouFind = travelUpTheDirectoryTreeTillYouFind; -function getPotentiallyRelativeFile(basePath, filePath) { - if (pathIsRelative(filePath)) { - return fsu.consistentPath(path.resolve(basePath, filePath)); - } - return fsu.consistentPath(filePath); -} -exports.getPotentiallyRelativeFile = getPotentiallyRelativeFile; -function getDirs(rootDir) { - var files = fs.readdirSync(rootDir); - var dirs = []; - for (var _i = 0, files_1 = files; _i < files_1.length; _i++) { - var file = files_1[_i]; - if (file[0] != '.') { - var filePath = rootDir + "/" + file; - var stat = fs.statSync(filePath); - if (stat.isDirectory()) { - dirs.push(filePath); - } - } - } - return dirs; -} -function createMap(arr) { - return arr.reduce(function (result, key) { - result[key] = true; - return result; - }, {}); -} -exports.createMap = createMap; -function reverseKeysAndValues(obj) { - var toret = {}; - Object.keys(obj).forEach(function (key) { - toret[obj[key]] = key; - }); - return toret; -} diff --git a/dist/main/typescriptBuffer.js b/dist/main/typescriptBuffer.js new file mode 100644 index 000000000..7d95d18f0 --- /dev/null +++ b/dist/main/typescriptBuffer.js @@ -0,0 +1,103 @@ +"use strict"; +Object.defineProperty(exports, "__esModule", { value: true }); +const tslib_1 = require("tslib"); +// A class to keep all changes to the buffer in sync with tsserver. This is mainly used with +// the editor panes, but is also useful for editor-less buffer changes (renameRefactor). +const atom_1 = require("atom"); +const events_1 = require("events"); +const utils_1 = require("./atom/utils"); +class TypescriptBuffer { + constructor(buffer, getClient) { + this.buffer = buffer; + this.getClient = getClient; + // Timestamps for buffer events + this.changedAt = 0; + this.changedAtBatch = 0; + this.events = new events_1.EventEmitter(); + this.subscriptions = new atom_1.CompositeDisposable(); + this.dispose = () => { + this.subscriptions.dispose(); + if (this.isOpen && this.clientPromise) { + this.clientPromise.then(client => client.executeClose({ file: this.buffer.getPath() })); + } + }; + this.onDidChange = () => { + this.changedAt = Date.now(); + }; + this.onDidSave = () => tslib_1.__awaiter(this, void 0, void 0, function* () { + // Check if there isn't a onDidStopChanging event pending. + const { changedAt, changedAtBatch } = this; + if (changedAt && changedAt > changedAtBatch) { + yield new Promise(resolve => this.events.once("changed", resolve)); + } + this.events.emit("saved"); + }); + this.onDidStopChanging = ({ changes }) => tslib_1.__awaiter(this, void 0, void 0, function* () { + // Don't update changedAt or emit any events if there are no actual changes or file isn't open + if (changes.length === 0 || !this.isOpen || !this.clientPromise) { + return; + } + this.changedAtBatch = Date.now(); + const client = yield this.clientPromise; + const filePath = this.buffer.getPath(); + for (const change of changes) { + const { start, oldExtent, newText } = change; + const end = { + endLine: start.row + oldExtent.row + 1, + endOffset: (oldExtent.row === 0 ? start.column + oldExtent.column : oldExtent.column) + 1 + }; + yield client.executeChange(Object.assign({}, end, { file: filePath, line: start.row + 1, offset: start.column + 1, insertString: newText })); + } + this.events.emit("changed"); + }); + this.subscriptions.add(buffer.onDidChange(this.onDidChange)); + this.subscriptions.add(buffer.onDidChangePath(this.onDidSave)); + this.subscriptions.add(buffer.onDidDestroy(this.dispose)); + this.subscriptions.add(buffer.onDidSave(this.onDidSave)); + this.subscriptions.add(buffer.onDidStopChanging(this.onDidStopChanging)); + this.open(); + } + open() { + return tslib_1.__awaiter(this, void 0, void 0, function* () { + const filePath = this.buffer.getPath(); + if (utils_1.isTypescriptFile(filePath)) { + // Set isOpen before we actually open the file to enqueue any changed events + this.isOpen = true; + this.clientPromise = this.getClient(filePath); + const client = yield this.clientPromise; + yield client.executeOpen({ + file: filePath, + fileContent: this.buffer.getText() + }); + this.events.emit("opened"); + } + }); + } + // If there are any pending changes, flush them out to the Typescript server + flush() { + return tslib_1.__awaiter(this, void 0, void 0, function* () { + if (this.changedAt > this.changedAtBatch) { + const prevDelay = this.buffer.stoppedChangingDelay; + try { + this.buffer.stoppedChangingDelay = 0; + this.buffer.scheduleDidStopChangingEvent(); + yield new Promise(resolve => { + const { dispose } = this.buffer.onDidStopChanging(() => { + dispose(); + resolve(); + }); + }); + } + finally { + this.buffer.stoppedChangingDelay = prevDelay; + } + } + }); + } + on(name, callback) { + this.events.on(name, callback); + return this; + } +} +exports.TypescriptBuffer = TypescriptBuffer; +//# sourceMappingURL=typescriptBuffer.js.map \ No newline at end of file diff --git a/dist/main/typescriptBuffer.js.map b/dist/main/typescriptBuffer.js.map new file mode 100644 index 000000000..32297cdc4 --- /dev/null +++ b/dist/main/typescriptBuffer.js.map @@ -0,0 +1 @@ +{"version":3,"file":"typescriptBuffer.js","sourceRoot":"","sources":["../../lib/main/typescriptBuffer.ts"],"names":[],"mappings":";;;AAAA,4FAA4F;AAC5F,wFAAwF;AACxF,+BAAwC;AAExC,mCAAmC;AACnC,wCAA6C;AAE7C;IAcE,YACS,MAA8B,EAC9B,SAAgD;QADhD,WAAM,GAAN,MAAM,CAAwB;QAC9B,cAAS,GAAT,SAAS,CAAuC;QAfzD,+BAA+B;QAC/B,cAAS,GAAW,CAAC,CAAA;QACrB,mBAAc,GAAW,CAAC,CAAA;QAQlB,WAAM,GAAG,IAAI,qBAAY,EAAE,CAAA;QAC3B,kBAAa,GAAG,IAAI,0BAAmB,EAAE,CAAA;QAqDjD,YAAO,GAAG;YACR,IAAI,CAAC,aAAa,CAAC,OAAO,EAAE,CAAA;YAE5B,EAAE,CAAC,CAAC,IAAI,CAAC,MAAM,IAAI,IAAI,CAAC,aAAa,CAAC,CAAC,CAAC;gBACtC,IAAI,CAAC,aAAa,CAAC,IAAI,CAAC,MAAM,IAC5B,MAAM,CAAC,YAAY,CAAC,EAAC,IAAI,EAAE,IAAI,CAAC,MAAM,CAAC,OAAO,EAAE,EAAC,CAAC,CAAC,CAAA;YACvD,CAAC;QACH,CAAC,CAAA;QAUD,gBAAW,GAAG;YACZ,IAAI,CAAC,SAAS,GAAG,IAAI,CAAC,GAAG,EAAE,CAAA;QAC7B,CAAC,CAAA;QAED,cAAS,GAAG;YACV,0DAA0D;YAC1D,MAAM,EAAC,SAAS,EAAE,cAAc,EAAC,GAAG,IAAI,CAAA;YACxC,EAAE,CAAC,CAAC,SAAS,IAAI,SAAS,GAAG,cAAc,CAAC,CAAC,CAAC;gBAC5C,MAAM,IAAI,OAAO,CAAC,OAAO,IAAI,IAAI,CAAC,MAAM,CAAC,IAAI,CAAC,SAAS,EAAE,OAAO,CAAC,CAAC,CAAA;YACpE,CAAC;YAED,IAAI,CAAC,MAAM,CAAC,IAAI,CAAC,OAAO,CAAC,CAAA;QAC3B,CAAC,CAAA,CAAA;QAED,sBAAiB,GAAG,CAAO,EAAC,OAAO,EAAmB;YACpD,8FAA8F;YAC9F,EAAE,CAAC,CAAC,OAAO,CAAC,MAAM,KAAK,CAAC,IAAI,CAAC,IAAI,CAAC,MAAM,IAAI,CAAC,IAAI,CAAC,aAAa,CAAC,CAAC,CAAC;gBAChE,MAAM,CAAA;YACR,CAAC;YAED,IAAI,CAAC,cAAc,GAAG,IAAI,CAAC,GAAG,EAAE,CAAA;YAEhC,MAAM,MAAM,GAAG,MAAM,IAAI,CAAC,aAAa,CAAA;YACvC,MAAM,QAAQ,GAAG,IAAI,CAAC,MAAM,CAAC,OAAO,EAAE,CAAA;YAEtC,GAAG,CAAC,CAAC,MAAM,MAAM,IAAI,OAAO,CAAC,CAAC,CAAC;gBAC7B,MAAM,EAAC,KAAK,EAAE,SAAS,EAAE,OAAO,EAAC,GAAG,MAAM,CAAA;gBAE1C,MAAM,GAAG,GAAG;oBACV,OAAO,EAAE,KAAK,CAAC,GAAG,GAAG,SAAS,CAAC,GAAG,GAAG,CAAC;oBACtC,SAAS,EAAE,CAAC,SAAS,CAAC,GAAG,KAAK,CAAC,GAAG,KAAK,CAAC,MAAM,GAAG,SAAS,CAAC,MAAM,GAAE,SAAS,CAAC,MAAM,CAAC,GAAG,CAAC;iBACzF,CAAA;gBAED,MAAM,MAAM,CAAC,aAAa,mBACrB,GAAG,IACN,IAAI,EAAE,QAAQ,EACd,IAAI,EAAE,KAAK,CAAC,GAAG,GAAG,CAAC,EACnB,MAAM,EAAE,KAAK,CAAC,MAAM,GAAG,CAAC,EACxB,YAAY,EAAE,OAAO,IACrB,CAAA;YACJ,CAAC;YAED,IAAI,CAAC,MAAM,CAAC,IAAI,CAAC,SAAS,CAAC,CAAA;QAC7B,CAAC,CAAA,CAAA;QA3GC,IAAI,CAAC,aAAa,CAAC,GAAG,CAAC,MAAM,CAAC,WAAW,CAAC,IAAI,CAAC,WAAW,CAAC,CAAC,CAAA;QAC5D,IAAI,CAAC,aAAa,CAAC,GAAG,CAAC,MAAM,CAAC,eAAe,CAAC,IAAI,CAAC,SAAS,CAAC,CAAC,CAAA;QAC9D,IAAI,CAAC,aAAa,CAAC,GAAG,CAAC,MAAM,CAAC,YAAY,CAAC,IAAI,CAAC,OAAO,CAAC,CAAC,CAAA;QACzD,IAAI,CAAC,aAAa,CAAC,GAAG,CAAC,MAAM,CAAC,SAAS,CAAC,IAAI,CAAC,SAAS,CAAC,CAAC,CAAA;QACxD,IAAI,CAAC,aAAa,CAAC,GAAG,CAAC,MAAM,CAAC,iBAAiB,CAAC,IAAI,CAAC,iBAAiB,CAAC,CAAC,CAAA;QAExE,IAAI,CAAC,IAAI,EAAE,CAAA;IACb,CAAC;IAEK,IAAI;;YACR,MAAM,QAAQ,GAAG,IAAI,CAAC,MAAM,CAAC,OAAO,EAAE,CAAA;YAEtC,EAAE,CAAC,CAAC,wBAAgB,CAAC,QAAQ,CAAC,CAAC,CAAC,CAAC;gBAC/B,4EAA4E;gBAC5E,IAAI,CAAC,MAAM,GAAG,IAAI,CAAA;gBAElB,IAAI,CAAC,aAAa,GAAG,IAAI,CAAC,SAAS,CAAC,QAAQ,CAAC,CAAA;gBAC7C,MAAM,MAAM,GAAG,MAAM,IAAI,CAAC,aAAa,CAAA;gBAEvC,MAAM,MAAM,CAAC,WAAW,CAAC;oBACvB,IAAI,EAAE,QAAQ;oBACd,WAAW,EAAE,IAAI,CAAC,MAAM,CAAC,OAAO,EAAE;iBACnC,CAAC,CAAA;gBAEF,IAAI,CAAC,MAAM,CAAC,IAAI,CAAC,QAAQ,CAAC,CAAA;YAC5B,CAAC;QACH,CAAC;KAAA;IAED,4EAA4E;IACtE,KAAK;;YACT,EAAE,CAAC,CAAC,IAAI,CAAC,SAAS,GAAG,IAAI,CAAC,cAAc,CAAC,CAAC,CAAC;gBACzC,MAAM,SAAS,GAAG,IAAI,CAAC,MAAM,CAAC,oBAAoB,CAAA;gBAClD,IAAI,CAAC;oBACH,IAAI,CAAC,MAAM,CAAC,oBAAoB,GAAG,CAAC,CAAA;oBACpC,IAAI,CAAC,MAAM,CAAC,4BAA4B,EAAE,CAAA;oBAC1C,MAAM,IAAI,OAAO,CAAC,OAAO;wBACvB,MAAM,EAAC,OAAO,EAAC,GAAG,IAAI,CAAC,MAAM,CAAC,iBAAiB,CAAC;4BAC9C,OAAO,EAAE,CAAA;4BACT,OAAO,EAAE,CAAA;wBACX,CAAC,CAAC,CAAA;oBACJ,CAAC,CAAC,CAAA;gBACJ,CAAC;wBAAS,CAAC;oBACT,IAAI,CAAC,MAAM,CAAC,oBAAoB,GAAG,SAAS,CAAA;gBAC9C,CAAC;YACH,CAAC;QACH,CAAC;KAAA;IAcD,EAAE,CAAC,IAAY,EAAE,QAAmB;QAClC,IAAI,CAAC,MAAM,CAAC,EAAE,CAAC,IAAI,EAAE,QAAQ,CAAC,CAAA;QAC9B,MAAM,CAAC,IAAI,CAAA;IACb,CAAC;CA8CF;AA9HD,4CA8HC"} \ No newline at end of file diff --git a/dist/main/typescriptEditorPane.js b/dist/main/typescriptEditorPane.js new file mode 100644 index 000000000..16739cd5d --- /dev/null +++ b/dist/main/typescriptEditorPane.js @@ -0,0 +1,183 @@ +"use strict"; +Object.defineProperty(exports, "__esModule", { value: true }); +const tslib_1 = require("tslib"); +const atom_space_pen_views_1 = require("atom-space-pen-views"); +const atom_1 = require("atom"); +const lodash_1 = require("lodash"); +const utils_1 = require("./atom/utils"); +const typescriptBuffer_1 = require("./typescriptBuffer"); +const tooltipManager = require("./atom/tooltipManager"); +class TypescriptEditorPane { + constructor(editor, opts) { + // Path to the project's tsconfig.json + this.configFile = ""; + this.isActive = false; + this.isTypescript = false; + this.isOpen = false; + this.occurrenceMarkers = []; + this.subscriptions = new atom_1.CompositeDisposable(); + this.onActivated = () => { + this.activeAt = Date.now(); + this.isActive = true; + if (this.isTypescript && this.filePath) { + this.opts.statusPanel.show(); + // The first activation might happen before we even have a client + if (this.client) { + this.client.executeGetErr({ + files: [this.filePath], + delay: 100 + }); + this.opts.statusPanel.setVersion(this.client.version); + } + } + this.opts.statusPanel.setTsConfigPath(this.configFile); + }; + this.onChanged = () => { + if (!this.client) + return; + this.opts.statusPanel.setBuildStatus(undefined); + this.client.executeGetErr({ + files: [this.filePath], + delay: 100 + }); + }; + this.onDeactivated = () => { + this.isActive = false; + this.opts.statusPanel.hide(); + }; + this.updateMarkers = lodash_1.debounce(() => { + if (!this.client) + return; + const pos = this.editor.getLastCursor().getBufferPosition(); + this.client.executeOccurances({ + file: this.filePath, + line: pos.row + 1, + offset: pos.column + 1 + }).then(result => { + this.clearOccurrenceMarkers(); + for (const ref of result.body) { + const marker = this.editor.markBufferRange(utils_1.spanToRange(ref)); + this.editor.decorateMarker(marker, { + type: "highlight", + class: "atom-typescript-occurrence" + }); + this.occurrenceMarkers.push(marker); + } + }).catch(() => this.clearOccurrenceMarkers()); + }, 100); + this.onDidChangeCursorPosition = ({ textChanged }) => { + if (!this.isTypescript) { + return; + } + if (textChanged) { + this.clearOccurrenceMarkers(); + return; + } + this.updateMarkers(); + }; + this.onDidDestroy = () => { + this.dispose(); + }; + this.onOpened = () => tslib_1.__awaiter(this, void 0, void 0, function* () { + this.client = yield this.opts.getClient(this.filePath); + this.subscriptions.add(this.editor.onDidChangeCursorPosition(this.onDidChangeCursorPosition)); + this.subscriptions.add(this.editor.onDidDestroy(this.onDidDestroy)); + // onOpened might trigger before onActivated so we can't rely on isActive flag + if (atom.workspace.getActiveTextEditor() === this.editor) { + this.isActive = true; + this.opts.statusPanel.setVersion(this.client.version); + } + if (this.isTypescript && this.filePath) { + this.client.executeGetErr({ + files: [this.filePath], + delay: 100 + }); + this.isOpen = true; + this.client.executeProjectInfo({ + needFileNameList: false, + file: this.filePath + }).then(result => { + this.configFile = result.body.configFileName; + if (this.isActive) { + this.opts.statusPanel.setTsConfigPath(this.configFile); + } + }, error => null); + } + }); + this.onSaved = () => { + this.filePath = this.editor.getPath(); + if (this.opts.onSave) { + this.opts.onSave(this); + } + this.compileOnSave(); + }; + this.editor = editor; + this.filePath = editor.getPath(); + this.opts = opts; + this.buffer = new typescriptBuffer_1.TypescriptBuffer(editor.buffer, opts.getClient) + .on("changed", this.onChanged) + .on("opened", this.onOpened) + .on("saved", this.onSaved); + this.isTypescript = isTypescriptGrammar(editor.getGrammar()); + // Add 'typescript-editor' class to the where typescript is active. + if (this.isTypescript) { + this.editor.element.classList.add('typescript-editor'); + } + this.subscriptions.add(editor.onDidChangeGrammar(grammar => { + this.isTypescript = isTypescriptGrammar(grammar); + })); + this.setupTooltipView(); + } + dispose() { + this.editor.element.classList.remove('typescript-editor'); + this.subscriptions.dispose(); + this.opts.onDispose(this); + } + clearOccurrenceMarkers() { + for (const marker of this.occurrenceMarkers) { + marker.destroy(); + } + } + compileOnSave() { + return tslib_1.__awaiter(this, void 0, void 0, function* () { + const { client } = this; + if (!client) + return; + const result = yield client.executeCompileOnSaveAffectedFileList({ + file: this.filePath + }); + this.opts.statusPanel.setBuildStatus(undefined); + const fileNames = lodash_1.flatten(result.body.map(project => project.fileNames)); + if (fileNames.length === 0) { + return; + } + try { + const promises = fileNames.map(file => client.executeCompileOnSaveEmitFile({ file })); + const saved = yield Promise.all(promises); + if (!saved.every(res => res.body)) { + throw new Error("Some files failed to emit"); + } + this.opts.statusPanel.setBuildStatus({ + success: true + }); + } + catch (error) { + console.error("Save failed with error", error); + this.opts.statusPanel.setBuildStatus({ + success: false + }); + } + }); + } + setupTooltipView() { + // subscribe for tooltips + // inspiration : https://github.com/chaika2013/ide-haskell + const editorView = atom_space_pen_views_1.$(atom.views.getView(this.editor)); + tooltipManager.attach(editorView, this.editor); + } +} +exports.TypescriptEditorPane = TypescriptEditorPane; +function isTypescriptGrammar(grammar) { + return grammar.scopeName === "source.ts" || grammar.scopeName === "source.tsx"; +} +//# sourceMappingURL=typescriptEditorPane.js.map \ No newline at end of file diff --git a/dist/main/typescriptEditorPane.js.map b/dist/main/typescriptEditorPane.js.map new file mode 100644 index 000000000..5b0c6158c --- /dev/null +++ b/dist/main/typescriptEditorPane.js.map @@ -0,0 +1 @@ +{"version":3,"file":"typescriptEditorPane.js","sourceRoot":"","sources":["../../lib/main/typescriptEditorPane.ts"],"names":[],"mappings":";;;AAAA,+DAAsC;AACtC,+BAAwC;AACxC,mCAAwC;AACxC,wCAAwC;AAExC,yDAAmD;AAEnD,wDAAuD;AASvD;IAqBE,YAAY,MAAwB,EAAE,IAAiB;QAdvD,sCAAsC;QACtC,eAAU,GAAW,EAAE,CAAA;QAGvB,aAAQ,GAAG,KAAK,CAAA;QAChB,iBAAY,GAAG,KAAK,CAAA;QAGZ,WAAM,GAAG,KAAK,CAAA;QAEb,sBAAiB,GAAoC,EAAE,CAAA;QAEvD,kBAAa,GAAG,IAAI,0BAAmB,EAAE,CAAA;QA+BlD,gBAAW,GAAG;YACZ,IAAI,CAAC,QAAQ,GAAG,IAAI,CAAC,GAAG,EAAE,CAAA;YAC1B,IAAI,CAAC,QAAQ,GAAG,IAAI,CAAA;YAEpB,EAAE,CAAC,CAAC,IAAI,CAAC,YAAY,IAAI,IAAI,CAAC,QAAQ,CAAC,CAAC,CAAC;gBACvC,IAAI,CAAC,IAAI,CAAC,WAAW,CAAC,IAAI,EAAE,CAAA;gBAE5B,iEAAiE;gBACjE,EAAE,CAAC,CAAC,IAAI,CAAC,MAAM,CAAC,CAAC,CAAC;oBAChB,IAAI,CAAC,MAAM,CAAC,aAAa,CAAC;wBACxB,KAAK,EAAE,CAAC,IAAI,CAAC,QAAQ,CAAC;wBACtB,KAAK,EAAE,GAAG;qBACX,CAAC,CAAA;oBAEF,IAAI,CAAC,IAAI,CAAC,WAAW,CAAC,UAAU,CAAC,IAAI,CAAC,MAAM,CAAC,OAAO,CAAC,CAAA;gBACvD,CAAC;YACH,CAAC;YAED,IAAI,CAAC,IAAI,CAAC,WAAW,CAAC,eAAe,CAAC,IAAI,CAAC,UAAU,CAAC,CAAA;QACxD,CAAC,CAAA;QAED,cAAS,GAAG;YACV,EAAE,CAAC,CAAC,CAAC,IAAI,CAAC,MAAM,CAAC;gBACf,MAAM,CAAA;YAER,IAAI,CAAC,IAAI,CAAC,WAAW,CAAC,cAAc,CAAC,SAAS,CAAC,CAAA;YAE/C,IAAI,CAAC,MAAM,CAAC,aAAa,CAAC;gBACxB,KAAK,EAAE,CAAC,IAAI,CAAC,QAAQ,CAAC;gBACtB,KAAK,EAAE,GAAG;aACX,CAAC,CAAA;QACJ,CAAC,CAAA;QAED,kBAAa,GAAG;YACd,IAAI,CAAC,QAAQ,GAAG,KAAK,CAAA;YACrB,IAAI,CAAC,IAAI,CAAC,WAAW,CAAC,IAAI,EAAE,CAAA;QAC9B,CAAC,CAAA;QAQD,kBAAa,GAAG,iBAAQ,CAAC;YACvB,EAAE,CAAC,CAAC,CAAC,IAAI,CAAC,MAAM,CAAC;gBACf,MAAM,CAAA;YAER,MAAM,GAAG,GAAG,IAAI,CAAC,MAAM,CAAC,aAAa,EAAE,CAAC,iBAAiB,EAAE,CAAA;YAE3D,IAAI,CAAC,MAAM,CAAC,iBAAiB,CAAC;gBAC5B,IAAI,EAAE,IAAI,CAAC,QAAQ;gBACnB,IAAI,EAAE,GAAG,CAAC,GAAG,GAAC,CAAC;gBACf,MAAM,EAAE,GAAG,CAAC,MAAM,GAAC,CAAC;aACrB,CAAC,CAAC,IAAI,CAAC,MAAM;gBACZ,IAAI,CAAC,sBAAsB,EAAE,CAAA;gBAE7B,GAAG,CAAC,CAAC,MAAM,GAAG,IAAI,MAAM,CAAC,IAAK,CAAC,CAAC,CAAC;oBAC/B,MAAM,MAAM,GAAG,IAAI,CAAC,MAAM,CAAC,eAAe,CAAC,mBAAW,CAAC,GAAG,CAAC,CAAC,CAAA;oBAC5D,IAAI,CAAC,MAAM,CAAC,cAAc,CAAC,MAAa,EAAE;wBACxC,IAAI,EAAE,WAAW;wBACjB,KAAK,EAAE,4BAA4B;qBACpC,CAAC,CAAA;oBACF,IAAI,CAAC,iBAAiB,CAAC,IAAI,CAAC,MAAM,CAAC,CAAA;gBACrC,CAAC;YACH,CAAC,CAAC,CAAC,KAAK,CAAC,MAAM,IAAI,CAAC,sBAAsB,EAAE,CAAC,CAAA;QAC/C,CAAC,EAAE,GAAG,CAAC,CAAA;QAEP,8BAAyB,GAAG,CAAC,EAAC,WAAW,EAAyB;YAChE,EAAE,CAAC,CAAC,CAAC,IAAI,CAAC,YAAY,CAAC,CAAC,CAAC;gBACvB,MAAM,CAAA;YACR,CAAC;YAED,EAAE,CAAC,CAAC,WAAW,CAAC,CAAC,CAAC;gBAChB,IAAI,CAAC,sBAAsB,EAAE,CAAA;gBAC7B,MAAM,CAAA;YACR,CAAC;YAED,IAAI,CAAC,aAAa,EAAE,CAAA;QACtB,CAAC,CAAA;QAED,iBAAY,GAAG;YACb,IAAI,CAAC,OAAO,EAAE,CAAA;QAChB,CAAC,CAAA;QAED,aAAQ,GAAG;YACT,IAAI,CAAC,MAAM,GAAG,MAAM,IAAI,CAAC,IAAI,CAAC,SAAS,CAAC,IAAI,CAAC,QAAQ,CAAC,CAAA;YAEtD,IAAI,CAAC,aAAa,CAAC,GAAG,CAAC,IAAI,CAAC,MAAM,CAAC,yBAAyB,CAAC,IAAI,CAAC,yBAAyB,CAAC,CAAC,CAAA;YAC7F,IAAI,CAAC,aAAa,CAAC,GAAG,CAAC,IAAI,CAAC,MAAM,CAAC,YAAY,CAAC,IAAI,CAAC,YAAY,CAAC,CAAC,CAAA;YAEnE,8EAA8E;YAC9E,EAAE,CAAC,CAAC,IAAI,CAAC,SAAS,CAAC,mBAAmB,EAAE,KAAK,IAAI,CAAC,MAAM,CAAC,CAAC,CAAC;gBACzD,IAAI,CAAC,QAAQ,GAAG,IAAI,CAAA;gBACpB,IAAI,CAAC,IAAI,CAAC,WAAW,CAAC,UAAU,CAAC,IAAI,CAAC,MAAM,CAAC,OAAO,CAAC,CAAA;YACvD,CAAC;YAED,EAAE,CAAC,CAAC,IAAI,CAAC,YAAY,IAAI,IAAI,CAAC,QAAQ,CAAC,CAAC,CAAC;gBACvC,IAAI,CAAC,MAAM,CAAC,aAAa,CAAC;oBACxB,KAAK,EAAE,CAAC,IAAI,CAAC,QAAQ,CAAC;oBACtB,KAAK,EAAE,GAAG;iBACX,CAAC,CAAA;gBAEF,IAAI,CAAC,MAAM,GAAG,IAAI,CAAA;gBAElB,IAAI,CAAC,MAAM,CAAC,kBAAkB,CAAC;oBAC7B,gBAAgB,EAAE,KAAK;oBACvB,IAAI,EAAE,IAAI,CAAC,QAAQ;iBACpB,CAAC,CAAC,IAAI,CAAC,MAAM;oBACZ,IAAI,CAAC,UAAU,GAAG,MAAM,CAAC,IAAK,CAAC,cAAc,CAAA;oBAE7C,EAAE,CAAC,CAAC,IAAI,CAAC,QAAQ,CAAC,CAAC,CAAC;wBAClB,IAAI,CAAC,IAAI,CAAC,WAAW,CAAC,eAAe,CAAC,IAAI,CAAC,UAAU,CAAC,CAAA;oBACxD,CAAC;gBACH,CAAC,EAAE,KAAK,IAAI,IAAI,CAAC,CAAA;YACnB,CAAC;QACH,CAAC,CAAA,CAAA;QAED,YAAO,GAAG;YACR,IAAI,CAAC,QAAQ,GAAG,IAAI,CAAC,MAAM,CAAC,OAAO,EAAE,CAAA;YAErC,EAAE,CAAC,CAAC,IAAI,CAAC,IAAI,CAAC,MAAM,CAAC,CAAC,CAAC;gBACrB,IAAI,CAAC,IAAI,CAAC,MAAM,CAAC,IAAI,CAAC,CAAA;YACxB,CAAC;YAED,IAAI,CAAC,aAAa,EAAE,CAAA;QACtB,CAAC,CAAA;QA1JC,IAAI,CAAC,MAAM,GAAG,MAAM,CAAA;QACpB,IAAI,CAAC,QAAQ,GAAG,MAAM,CAAC,OAAO,EAAE,CAAA;QAChC,IAAI,CAAC,IAAI,GAAG,IAAI,CAAA;QAChB,IAAI,CAAC,MAAM,GAAG,IAAI,mCAAgB,CAAC,MAAM,CAAC,MAAM,EAAE,IAAI,CAAC,SAAS,CAAC;aAC9D,EAAE,CAAC,SAAS,EAAE,IAAI,CAAC,SAAS,CAAC;aAC7B,EAAE,CAAC,QAAQ,EAAE,IAAI,CAAC,QAAQ,CAAC;aAC3B,EAAE,CAAC,OAAO,EAAE,IAAI,CAAC,OAAO,CAAC,CAAA;QAE5B,IAAI,CAAC,YAAY,GAAG,mBAAmB,CAAC,MAAM,CAAC,UAAU,EAAE,CAAC,CAAA;QAE5D,sFAAsF;QACtF,EAAE,CAAC,CAAC,IAAI,CAAC,YAAY,CAAC,CAAC,CAAC;YACtB,IAAI,CAAC,MAAM,CAAC,OAAO,CAAC,SAAS,CAAC,GAAG,CAAC,mBAAmB,CAAC,CAAA;QACxD,CAAC;QAED,IAAI,CAAC,aAAa,CAAC,GAAG,CAAC,MAAM,CAAC,kBAAkB,CAAC,OAAO;YACtD,IAAI,CAAC,YAAY,GAAG,mBAAmB,CAAC,OAAO,CAAC,CAAA;QAClD,CAAC,CAAC,CAAC,CAAA;QAEH,IAAI,CAAC,gBAAgB,EAAE,CAAA;IACzB,CAAC;IAED,OAAO;QACL,IAAI,CAAC,MAAM,CAAC,OAAO,CAAC,SAAS,CAAC,MAAM,CAAC,mBAAmB,CAAC,CAAA;QACzD,IAAI,CAAC,aAAa,CAAC,OAAO,EAAE,CAAA;QAC5B,IAAI,CAAC,IAAI,CAAC,SAAS,CAAC,IAAI,CAAC,CAAA;IAC3B,CAAC;IAwCD,sBAAsB;QACpB,GAAG,CAAC,CAAC,MAAM,MAAM,IAAI,IAAI,CAAC,iBAAiB,CAAC,CAAC,CAAC;YAC5C,MAAM,CAAC,OAAO,EAAE,CAAA;QAClB,CAAC;IACH,CAAC;IAsFK,aAAa;;YACjB,MAAM,EAAC,MAAM,EAAC,GAAG,IAAI,CAAA;YACrB,EAAE,CAAC,CAAC,CAAC,MAAM,CAAC;gBACV,MAAM,CAAA;YAER,MAAM,MAAM,GAAG,MAAM,MAAM,CAAC,oCAAoC,CAAC;gBAC/D,IAAI,EAAE,IAAI,CAAC,QAAQ;aACpB,CAAC,CAAA;YAEF,IAAI,CAAC,IAAI,CAAC,WAAW,CAAC,cAAc,CAAC,SAAS,CAAC,CAAA;YAE/C,MAAM,SAAS,GAAG,gBAAO,CAAC,MAAM,CAAC,IAAI,CAAC,GAAG,CAAC,OAAO,IAAI,OAAO,CAAC,SAAS,CAAC,CAAC,CAAA;YAExE,EAAE,CAAC,CAAC,SAAS,CAAC,MAAM,KAAK,CAAC,CAAC,CAAC,CAAC;gBAC3B,MAAM,CAAA;YACR,CAAC;YAED,IAAI,CAAC;gBACH,MAAM,QAAQ,GAAG,SAAS,CAAC,GAAG,CAAC,IAAI,IAAI,MAAM,CAAC,4BAA4B,CAAC,EAAC,IAAI,EAAC,CAAC,CAAC,CAAA;gBACnF,MAAM,KAAK,GAAG,MAAM,OAAO,CAAC,GAAG,CAAC,QAAQ,CAAC,CAAA;gBAEzC,EAAE,CAAC,CAAC,CAAC,KAAK,CAAC,KAAK,CAAC,GAAG,IAAI,GAAG,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;oBAClC,MAAM,IAAI,KAAK,CAAC,2BAA2B,CAAC,CAAA;gBAC9C,CAAC;gBAED,IAAI,CAAC,IAAI,CAAC,WAAW,CAAC,cAAc,CAAC;oBACnC,OAAO,EAAE,IAAI;iBACd,CAAC,CAAA;YAEJ,CAAC;YAAC,KAAK,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC;gBACf,OAAO,CAAC,KAAK,CAAC,wBAAwB,EAAE,KAAK,CAAC,CAAA;gBAC9C,IAAI,CAAC,IAAI,CAAC,WAAW,CAAC,cAAc,CAAC;oBACnC,OAAO,EAAE,KAAK;iBACf,CAAC,CAAA;YACJ,CAAC;QACH,CAAC;KAAA;IAED,gBAAgB;QACd,yBAAyB;QACzB,0DAA0D;QAC1D,MAAM,UAAU,GAAG,wBAAC,CAAC,IAAI,CAAC,KAAK,CAAC,OAAO,CAAC,IAAI,CAAC,MAAM,CAAC,CAAC,CAAA;QACrD,cAAc,CAAC,MAAM,CAAC,UAAU,EAAE,IAAI,CAAC,MAAM,CAAC,CAAA;IAChD,CAAC;CACF;AA7ND,oDA6NC;AAED,6BAA6B,OAA0B;IACrD,MAAM,CAAC,OAAO,CAAC,SAAS,KAAK,WAAW,IAAI,OAAO,CAAC,SAAS,KAAK,YAAY,CAAA;AAChF,CAAC"} \ No newline at end of file diff --git a/dist/main/utils/fsUtil.js b/dist/main/utils/fsUtil.js deleted file mode 100644 index 69cfb6d28..000000000 --- a/dist/main/utils/fsUtil.js +++ /dev/null @@ -1,30 +0,0 @@ -"use strict"; -function consistentPath(filePath) { - return filePath.split('\\').join('/'); -} -exports.consistentPath = consistentPath; -var path = require("path"); -function resolve() { - var args = []; - for (var _i = 0; _i < arguments.length; _i++) { - args[_i] = arguments[_i]; - } - return consistentPath(path.resolve.apply(path, args)); -} -exports.resolve = resolve; -function isExt(path, ext) { - return path && path.indexOf(ext, path.length - ext.length) !== -1; -} -exports.isExt = isExt; -function makeRelativePath(relativeFolder, filePath) { - var relativePath = path.relative(relativeFolder, filePath).split('\\').join('/'); - if (relativePath[0] !== '.') { - relativePath = './' + relativePath; - } - return relativePath; -} -exports.makeRelativePath = makeRelativePath; -function removeExt(filePath) { - return filePath.substr(0, filePath.lastIndexOf('.')); -} -exports.removeExt = removeExt; diff --git a/dist/typescript/makeTypeScriptGlobal.js b/dist/typescript/makeTypeScriptGlobal.js deleted file mode 100644 index 56e3d65d7..000000000 --- a/dist/typescript/makeTypeScriptGlobal.js +++ /dev/null @@ -1,18 +0,0 @@ -"use strict"; -var path_1 = require("path"); -global.stack = function () { - console.error(new Error().stack); -}; -function makeTsGlobal(typescriptPath) { - if (typescriptPath) { - if (!path_1.isAbsolute(typescriptPath)) { - throw new Error("Path to Typescript \"" + typescriptPath + "\" is not absolute"); - } - typescriptPath = typescriptPath.trim(); - } - else { - typescriptPath = "typescript"; - } - global.ts = require(typescriptPath); -} -exports.makeTsGlobal = makeTsGlobal; diff --git a/dist/worker/child.js b/dist/worker/child.js deleted file mode 100644 index 7e4f343dc..000000000 --- a/dist/worker/child.js +++ /dev/null @@ -1,15 +0,0 @@ -"use strict"; -var typescriptServices = ''; -if (process.argv.length > 2) { - typescriptServices = process.argv[2]; -} -var makeTypeScriptGlobal_1 = require("../typescript/makeTypeScriptGlobal"); -makeTypeScriptGlobal_1.makeTsGlobal(typescriptServices); -var typescriptServices_1 = require("../main/lang/typescriptServices"); -typescriptServices_1.setTypescriptServices(typescriptServices); -var workerLib = require("./lib/workerLib"); -var child = new workerLib.Child(); -var projectCache = require("../main/lang/projectCache"); -projectCache.fixChild(child); -var projectService = require("../main/lang/projectService"); -child.registerAllFunctionsExportedFromAsResponders(projectService); diff --git a/dist/worker/debug.js b/dist/worker/debug.js deleted file mode 100644 index a77b0f234..000000000 --- a/dist/worker/debug.js +++ /dev/null @@ -1,3 +0,0 @@ -"use strict"; -exports.debugAll = false; -exports.debugSync = false || exports.debugAll; diff --git a/dist/worker/lib/workerLib.js b/dist/worker/lib/workerLib.js deleted file mode 100644 index fbb629850..000000000 --- a/dist/worker/lib/workerLib.js +++ /dev/null @@ -1,245 +0,0 @@ -"use strict"; -var __extends = (this && this.__extends) || function (d, b) { - for (var p in b) if (b.hasOwnProperty(p)) d[p] = b[p]; - function __() { this.constructor = d; } - d.prototype = b === null ? Object.create(b) : (__.prototype = b.prototype, new __()); -}; -var childprocess = require("child_process"); -var exec = childprocess.exec; -var spawn = childprocess.spawn; -var path = require("path"); -function createId() { - return 'xxxxxxxx-xxxx-4xxx-yxxx-xxxxxxxxxxxx'.replace(/[xy]/g, function (c) { - var r = Math.random() * 16 | 0, v = c == 'x' ? r : (r & 0x3 | 0x8); - return v.toString(16); - }); -} -var orphanExitCode = 100; -var RequesterResponder = (function () { - function RequesterResponder() { - var _this = this; - this.currentListeners = {}; - this.currentLastOfType = {}; - this.pendingRequests = []; - this.pendingRequestsChanged = function (pending) { return null; }; - this.sendToIpcHeart = function (data, message) { - if (!_this.getProcess()) { - console.log('PARENT ERR: no child when you tried to send :', message); - return Promise.reject(new Error("No worker active to recieve message: " + message)); - } - if (!_this.currentListeners[message]) - _this.currentListeners[message] = {}; - var id = createId(); - var promise = new Promise(function (resolve, reject) { - _this.currentListeners[message][id] = { resolve: resolve, reject: reject, promise: promise }; - }); - _this.pendingRequests.push(message); - _this.pendingRequestsChanged(_this.pendingRequests); - _this.getProcess().send({ message: message, id: id, data: data, request: true }); - return promise; - }; - this.responders = {}; - this.processRequest = function (m) { - var parsed = m; - if (!parsed.message || !_this.responders[parsed.message]) { - return; - } - var message = parsed.message; - var responsePromise; - try { - responsePromise = _this.responders[message](parsed.data); - } - catch (err) { - responsePromise = Promise.reject({ method: message, message: err.message, stack: err.stack, details: err.details || {} }); - } - responsePromise - .then(function (response) { - _this.getProcess().send({ - message: message, - id: parsed.id, - data: response, - error: null, - request: false - }); - }) - .catch(function (error) { - _this.getProcess().send({ - message: message, - id: parsed.id, - data: null, - error: error, - request: false - }); - }); - }; - } - RequesterResponder.prototype.processResponse = function (m) { - var parsed = m; - this.pendingRequests.shift(); - this.pendingRequestsChanged(this.pendingRequests); - if (!parsed.message || !parsed.id) { - console.log('PARENT ERR: Invalid JSON data from child:', m); - } - else if (!this.currentListeners[parsed.message] || !this.currentListeners[parsed.message][parsed.id]) { - console.log('PARENT ERR: No one was listening:', parsed.message, parsed.data); - } - else { - if (parsed.error) { - this.currentListeners[parsed.message][parsed.id].reject(parsed.error); - console.log(parsed.error); - console.log(parsed.error.stack); - } - else { - this.currentListeners[parsed.message][parsed.id].resolve(parsed.data); - } - delete this.currentListeners[parsed.message][parsed.id]; - if (this.currentLastOfType[parsed.message]) { - var last_1 = this.currentLastOfType[parsed.message]; - delete this.currentLastOfType[parsed.message]; - var lastPromise = this.sendToIpcHeart(last_1.data, parsed.message); - lastPromise.then(function (res) { return last_1.defer.resolve(res); }, function (rej) { return last_1.defer.reject(rej); }); - } - } - }; - RequesterResponder.prototype.sendToIpc = function (func) { - var _this = this; - var message = func.name; - return function (data) { return _this.sendToIpcHeart(data, message); }; - }; - RequesterResponder.prototype.sendToIpcOnlyLast = function (func, defaultResponse) { - var _this = this; - return function (data) { - var message = func.name; - if (!_this.getProcess()) { - console.log('PARENT ERR: no child when you tried to send :', message); - return Promise.reject(new Error("No worker active to recieve message: " + message)); - } - if (!Object.keys(_this.currentListeners[message] || {}).length) { - return _this.sendToIpcHeart(data, message); - } - else { - if (_this.currentLastOfType[message]) { - _this.currentLastOfType[message].defer.resolve(defaultResponse); - } - var promise_1 = new Promise(function (resolve, reject) { - _this.currentLastOfType[message] = { - data: data, - defer: { promise: promise_1, resolve: resolve, reject: reject } - }; - }); - return promise_1; - } - }; - }; - RequesterResponder.prototype.addToResponders = function (func) { - this.responders[func.name] = func; - }; - RequesterResponder.prototype.registerAllFunctionsExportedFromAsResponders = function (aModule) { - var _this = this; - Object.keys(aModule) - .filter(function (funcName) { return typeof aModule[funcName] == 'function'; }) - .forEach(function (funcName) { return _this.addToResponders(aModule[funcName]); }); - }; - return RequesterResponder; -}()); -var Parent = (function (_super) { - __extends(Parent, _super); - function Parent() { - var _this = _super.apply(this, arguments) || this; - _this.node = process.execPath; - _this.gotENOENTonSpawnNode = false; - _this.getProcess = function () { return _this.child; }; - _this.stopped = false; - return _this; - } - Parent.prototype.startWorker = function (childJsPath, terminalError, customArguments) { - var _this = this; - try { - var spawnEnv = (process.platform === 'linux') ? Object.create(process.env) : {}; - spawnEnv['ELECTRON_RUN_AS_NODE'] = 1; - this.child = spawn(this.node, [ - childJsPath - ].concat(customArguments), { - cwd: path.dirname(childJsPath), - env: spawnEnv, - stdio: ['ipc'] - }); - this.child.on('error', function (err) { - if (err.code === "ENOENT" && err.path === _this.node) { - _this.gotENOENTonSpawnNode = true; - } - console.log('CHILD ERR ONERROR:', err.message, err.stack, err); - _this.child = null; - }); - this.child.on('message', function (message) { - if (message.request) { - _this.processRequest(message); - } - else { - _this.processResponse(message); - } - }); - this.child.stderr.on('data', function (err) { - console.log("CHILD ERR STDERR:", err.toString()); - }); - this.child.on('close', function (code) { - if (_this.stopped) { - return; - } - if (code === orphanExitCode) { - _this.startWorker(childJsPath, terminalError, customArguments); - } - else if (_this.gotENOENTonSpawnNode) { - terminalError(new Error('gotENOENTonSpawnNode')); - } - else { - console.log("ts worker restarting. Don't know why it stopped with code:", code); - _this.startWorker(childJsPath, terminalError, customArguments); - } - }); - } - catch (err) { - terminalError(err); - } - }; - Parent.prototype.stopWorker = function () { - this.stopped = true; - if (!this.child) - return; - try { - this.child.kill('SIGTERM'); - } - catch (ex) { - console.error('failed to kill worker child'); - } - this.child = null; - }; - return Parent; -}(RequesterResponder)); -exports.Parent = Parent; -var Child = (function (_super) { - __extends(Child, _super); - function Child() { - var _this = _super.call(this) || this; - _this.getProcess = function () { return process; }; - _this.keepAlive(); - process.on('message', function (message) { - if (message.request) { - _this.processRequest(message); - } - else { - _this.processResponse(message); - } - }); - return _this; - } - Child.prototype.keepAlive = function () { - setInterval(function () { - if (!process.connected) { - process.exit(orphanExitCode); - } - }, 1000); - }; - return Child; -}(RequesterResponder)); -exports.Child = Child; diff --git a/dist/worker/parent.js b/dist/worker/parent.js deleted file mode 100644 index 5191ee634..000000000 --- a/dist/worker/parent.js +++ /dev/null @@ -1,83 +0,0 @@ -"use strict"; -var debug_1 = require("./debug"); -var childprocess = require("child_process"); -var exec = childprocess.exec; -var spawn = childprocess.spawn; -var workerLib = require("./lib/workerLib"); -var atomConfig = require("../main/atom/atomConfig"); -var parent = new workerLib.Parent(); -var mainPanel = require("../main/atom/views/mainPanelView"); -parent.pendingRequestsChanged = function (pending) { - if (!mainPanel.panelView) - return; - mainPanel.panelView.updatePendingRequests(pending); -}; -if (debug_1.debugSync) { - parent.sendToIpc = function (x) { return x; }; - parent.sendToIpcOnlyLast = function (x) { return x; }; -} -function startWorker() { - if (!debug_1.debugSync) { - parent.startWorker(__dirname + '/child.js', showError, atomConfig.typescriptServices ? [atomConfig.typescriptServices] : []); - } -} -exports.startWorker = startWorker; -function stopWorker() { - if (!debug_1.debugSync) { - parent.stopWorker(); - } -} -exports.stopWorker = stopWorker; -function showError(error) { - var message = "Failed to start a child TypeScript worker. Atom-TypeScript is disabled."; - if (process.platform === "win32") { - message = message + " Make sure you have 'node' installed and available in your system path."; - } - atom.notifications.addError(message, { dismissable: true }); - if (error) { - console.error('Failed to activate ts-worker:', error); - } -} -function catchCommonErrors(func) { - return function (q) { return func(q).catch(function (err) { - return Promise.reject(err); - }); }; -} -var projectService = require("../main/lang/projectService"); -exports.echo = catchCommonErrors(parent.sendToIpc(projectService.echo)); -exports.quickInfo = catchCommonErrors(parent.sendToIpc(projectService.quickInfo)); -exports.build = catchCommonErrors(parent.sendToIpc(projectService.build)); -exports.getCompletionsAtPosition = parent.sendToIpcOnlyLast(projectService.getCompletionsAtPosition, { - completions: [], - endsInPunctuation: false -}); -exports.emitFile = catchCommonErrors(parent.sendToIpc(projectService.emitFile)); -exports.formatDocument = catchCommonErrors(parent.sendToIpc(projectService.formatDocument)); -exports.formatDocumentRange = catchCommonErrors(parent.sendToIpc(projectService.formatDocumentRange)); -exports.getDefinitionsAtPosition = catchCommonErrors(parent.sendToIpc(projectService.getDefinitionsAtPosition)); -exports.updateText = catchCommonErrors(parent.sendToIpc(projectService.updateText)); -exports.editText = catchCommonErrors(parent.sendToIpc(projectService.editText)); -exports.errorsForFile = catchCommonErrors(parent.sendToIpc(projectService.errorsForFile)); -exports.getSignatureHelps = catchCommonErrors(parent.sendToIpc(projectService.getSignatureHelps)); -exports.getRenameInfo = catchCommonErrors(parent.sendToIpc(projectService.getRenameInfo)); -exports.getRelativePathsInProject = catchCommonErrors(parent.sendToIpc(projectService.getRelativePathsInProject)); -exports.debugLanguageServiceHostVersion = parent.sendToIpc(projectService.debugLanguageServiceHostVersion); -exports.getProjectFileDetails = parent.sendToIpc(projectService.getProjectFileDetails); -exports.getNavigationBarItems = parent.sendToIpc(projectService.getNavigationBarItems); -exports.getSemtanticTree = parent.sendToIpc(projectService.getSemtanticTree); -exports.getNavigateToItems = parent.sendToIpc(projectService.getNavigateToItems); -exports.getReferences = parent.sendToIpc(projectService.getReferences); -exports.getAST = parent.sendToIpc(projectService.getAST); -exports.getASTFull = parent.sendToIpc(projectService.getASTFull); -exports.getDependencies = parent.sendToIpc(projectService.getDependencies); -exports.getQuickFixes = parent.sendToIpc(projectService.getQuickFixes); -exports.applyQuickFix = parent.sendToIpc(projectService.applyQuickFix); -exports.getOutput = parent.sendToIpc(projectService.getOutput); -exports.getOutputJs = parent.sendToIpc(projectService.getOutputJs); -exports.getOutputJsStatus = parent.sendToIpc(projectService.getOutputJsStatus); -exports.softReset = parent.sendToIpc(projectService.softReset); -exports.getRenameFilesRefactorings = parent.sendToIpc(projectService.getRenameFilesRefactorings); -exports.createProject = parent.sendToIpc(projectService.createProject); -exports.toggleBreakpoint = parent.sendToIpc(projectService.toggleBreakpoint); -var queryParent = require("./queryParent"); -parent.registerAllFunctionsExportedFromAsResponders(queryParent); diff --git a/dist/worker/queryParent.js b/dist/worker/queryParent.js deleted file mode 100644 index 66e203896..000000000 --- a/dist/worker/queryParent.js +++ /dev/null @@ -1,98 +0,0 @@ -"use strict"; -var resolve = Promise.resolve.bind(Promise); -var tsconfig = require("../main/tsconfig/tsconfig"); -var atomUtils; -var mainPanelView; -try { - require('atom'); - atomUtils = require('../main/atom/atomUtils'); - mainPanelView = require('../main/atom/views/mainPanelView'); -} -catch (ex) { -} -function echoNumWithModification(query) { - return Promise.resolve({ num: query.num + 10 }); -} -exports.echoNumWithModification = echoNumWithModification; -function getUpdatedTextForUnsavedEditors(query) { - var editors = atomUtils.getTypeScriptEditorsWithPaths().filter(function (editor) { return editor.isModified(); }); - return resolve({ - editors: editors.map(function (e) { - return { filePath: e.getPath(), text: e.getText() }; - }) - }); -} -exports.getUpdatedTextForUnsavedEditors = getUpdatedTextForUnsavedEditors; -function getOpenEditorPaths(query) { - var paths = atomUtils.getOpenTypeScritEditorsConsistentPaths(); - return resolve({ - filePaths: paths - }); -} -exports.getOpenEditorPaths = getOpenEditorPaths; -function setConfigurationError(query) { - var errors = []; - if (query.error) { - if (query.error.message == tsconfig.errors.GET_PROJECT_JSON_PARSE_FAILED) { - var details = query.error.details; - errors = [ - { - filePath: details.projectFilePath, - startPos: { line: 0, col: 0 }, - endPos: { line: 0, col: 0 }, - message: "The project file contains invalid JSON", - preview: details.projectFilePath, - } - ]; - } - if (query.error.message == tsconfig.errors.GET_PROJECT_PROJECT_FILE_INVALID_OPTIONS) { - var details = query.error.details; - errors = [ - { - filePath: details.projectFilePath, - startPos: { line: 0, col: 0 }, - endPos: { line: 0, col: 0 }, - message: "The project file contains invalid options", - preview: details.errorMessage, - } - ]; - } - if (query.error.message == tsconfig.errors.GET_PROJECT_GLOB_EXPAND_FAILED) { - var details = query.error.details; - errors = [ - { - filePath: details.projectFilePath, - startPos: { line: 0, col: 0 }, - endPos: { line: 0, col: 0 }, - message: "Failed to expand the glob for the project file", - preview: details.errorMessage, - } - ]; - } - if (query.error.message === tsconfig.errors.GET_PROJECT_NO_PROJECT_FOUND) { - var details = query.error.details; - errors = [ - { - filePath: details.projectFilePath, - startPos: { line: 0, col: 0 }, - endPos: { line: 0, col: 0 }, - message: "No project file found. Please use the 'Create tsconfig.json project file' command", - preview: '', - } - ]; - } - } - mainPanelView.errorView.setErrors(query.projectFilePath, errors); - return resolve({}); -} -exports.setConfigurationError = setConfigurationError; -function notifySuccess(query) { - atom.notifications.addSuccess(query.message); - return resolve({}); -} -exports.notifySuccess = notifySuccess; -function buildUpdate(query) { - mainPanelView.panelView.setBuildProgress(query); - return resolve({}); -} -exports.buildUpdate = buildUpdate; diff --git a/docs/CHANGELOG.md b/docs/CHANGELOG.md index dd0bcd799..ae34e6927 100644 --- a/docs/CHANGELOG.md +++ b/docs/CHANGELOG.md @@ -5,6 +5,9 @@ We only plan to *strictly* document the breaking changes. The rest is optional. # Planned (No breaking changes staged) +# v11.0.0 +* Major rewrite using `tsserver` API for the best compatibility with the current versions of Typescript. + # v7.0.0 * Removed the (already ignored in any significant way) `version` option from tsconfig. [More](https://github.com/TypeStrong/atom-typescript/issues/617) @@ -32,4 +35,3 @@ We only plan to *strictly* document the breaking changes. The rest is optional. # 0.x * Initial releases - diff --git a/docs/dependency-view.md b/docs/dependency-view.md deleted file mode 100644 index 2b43aa3b9..000000000 --- a/docs/dependency-view.md +++ /dev/null @@ -1,31 +0,0 @@ -# In Out -* Nodes that do not depend on anything are colored green : These are probably utilities. -* Nodes that only depend on other stuff are colored blue: These are probably application entry points. - -![](https://raw.githubusercontent.com/TypeStrong/atom-typescript-examples/master/screens/dependencyView/inOut.png) - -# Circular -Circular dependencies are highlighted in red - -![](https://raw.githubusercontent.com/TypeStrong/atom-typescript-examples/master/screens/dependencyView/circular.png) - -# Filter -You can filter particular nodes by specifying their name - -![](https://raw.githubusercontent.com/TypeStrong/atom-typescript-examples/master/screens/dependencyView/filter.png) - -# Hover -When you hover over a node -* Red arrow denote stuff this file depends upon. Implies that this file cannot be extracted without also moving these files. -* Green arrows denote stuff that depends on this file. Green as this means the code in this file is moveable to another project and these links will play no part in that. - -![](https://raw.githubusercontent.com/TypeStrong/atom-typescript-examples/master/screens/dependencyView/teaser.png) - -# Size -Size is based on average of in-degree and out-degree: - -![](https://raw.githubusercontent.com/TypeStrong/atom-typescript-examples/master/screens/dependencyView/size.png) - -# Distance -Distance is determined by how much of the file path is common between two nodes: -![](https://raw.githubusercontent.com/TypeStrong/atom-typescript-examples/master/screens/dependencyView/distance.png) diff --git a/docs/faq.md b/docs/faq.md index 271f6584e..6f8dea1f6 100644 --- a/docs/faq.md +++ b/docs/faq.md @@ -1,66 +1,16 @@ # FAQ -## Declaration packages (@types) are not loaded -Declaration packages, such as those installed via @types on npm, must be declared in the tsconfig.json "types" field. While Typescript's compiler automatically includes them when no "types" field is given, atom-typescript does not. This will hopefully be fixed soon (see #1054). - ## Syntax Highlighting is bad For grammar issues go here : https://github.com/Microsoft/TypeScript-TmLanguage/issues and link back to us if you want us to pull from upstream 🌹. More on how our grammar is managed : https://github.com/TypeStrong/atom-typescript/blob/master/docs/grammar.md -## I keep getting changes to tsconfig.json -This is probably because of us keeping `files` updated with the `filesGlob` option. The reason why we do this is because the official `tsconfig.json` spec does not support `filesGlob`. Therefore we keep `files` in sync with the `filesGlob` so that your team mates can use whatever editor they prefer (sublime text, visual studio etc.). - -You can now disable this behavior by setting the `rewriteTsconfig` flag to `false` in your project's `tsconfig.json` under the `atom` key. - -[Further Details](https://github.com/TypeStrong/atom-typescript/blob/master/docs/tsconfig.md#atom) - -## For really large projects atom-typescript gets slow -If you have `tsconfig.json` in a folder that contains `node_modules`, atom-typescript might become slow (due to extensive file listing). Two possible fixes: -* Move `tsconfig.json` into a sub folder e.g. `src` -* Add a `filesGlob` that excludes `node_modules` e.g.: - -```ts -"filesGlob" : [ - "**/*.ts", - "**/*.tsx", - "!node_modules/**", -]; -``` - -[Further Details](https://github.com/TypeStrong/atom-typescript/issues/648). - -## I don't want atom-typescript compiling my js -Set `compileOnSave : false` in your tsconfig.json (https://github.com/TypeStrong/atom-typescript/blob/master/docs/tsconfig.md#compileonsave). Then you've got all the intellisense / refactoring goodness of atom-typescript but no generated JavaScript. Why is this useful? Well you might be using something else for your build such as [ts-loader](https://github.com/TypeStrong/ts-loader) or [tsify](https://github.com/TypeStrong/tsify) or [gulp-typescript](https://github.com/ivogabe/gulp-typescript). - ## Which version of TypeScript does atom-typescript use? -You can see the date `typescript` dependency was updated in our [`package.json`](https://github.com/TypeStrong/atom-typescript/blob/master/package.json) e.g. `"typescript": "2.1.0-dev.20161023"` means it's using the nightly build published on `2016-10-23`). - -## Can I use a custom TypeScript compiler? -If it conforms the latest TypeScript services API then yes! Just set the path to `typescriptServices.js` in the package options. - -## Can I use an alternate transpiler? -Atom-typescript supports using Babel as an alternate ES5 transpiler in coordination with the TypeScript language service. This may be useful if TypeScript does not yet support transpiling a certain feature correctly (for example [scope per for loop iteration with let](https://github.com/Microsoft/TypeScript/issues/3915)). - -To enable using Babel as the transpiler, make these changes to your `tsconfig.json` file: - -**1:** Add this key in the root: - -```js -{ - "externalTranspiler": "babel" -} -``` -**2:** Set the `target` compiler option to `"es6"`. This is not *technically* required, but if you don't do this, you'll just be transpiling an already-transpiled file. - -Note that atom-typescript's Babel integraion works with in concert with the `removeComments`, `sourceMap`, and `inlineSourceMap` compiler options settings in `tsconfig.json`, so those items should just work as expected. Any source maps should be doubly-mapped back to the original TypeScript. - -## I prefer single (or double) quotes -You can set that in the package settings https://atom.io/docs/latest/using-atom-atom-packages#package-settings +Your current version installed in your `node_modules`. This gets determined once per open file so you might want to re-open your panes, if you've updated Typescript in your project. ## Atom Typescript is complaining about not finding files or other weird errors -You probably deleted them or added them or moved them around. We don't watch the file system as it is memory intensive and unreliable across operating systems. You can ask atom-typescript to do a rescan of your file system using the `sync` command (https://github.com/TypeStrong/atom-typescript#sync) +You probably deleted them or added them or moved them around. The Typescript compiler is decent about keeping track of moving files, but sometimes things can go out of sync and in that case it's best to simply reset the editor using `Window: Reload` command. ## Failed to Update This can happen particularly on windows ([relevant issue](https://github.com/TypeStrong/atom-typescript/issues/195)) as it is not possible to delete a file if it is executing. Close all atom instances and run the following commands: diff --git a/docs/grammar.md b/docs/grammar.md index d77f7a7d5..6f8d8ad19 100644 --- a/docs/grammar.md +++ b/docs/grammar.md @@ -1,6 +1,6 @@ # CSON grammar -Atom works with a CSON grammar. We generate this from Microsoft supported grammar files. This is the code https://github.com/TypeStrong/atom-typescript/blob/master/scripts/grammar.js run using `npm run build` that updates our grammar file. +Atom works with a CSON grammar. We generate this from Microsoft supported grammar files. This is the code https://github.com/TypeStrong/atom-typescript/blob/master/scripts/grammar.js run using `npm run grammar` that updates our grammar file. For grammar issues go here : https://github.com/Microsoft/TypeScript-TmLanguage/issues and link back to us if you want us to pull from upstream :rose:. @@ -10,19 +10,3 @@ https://discuss.atom.io/t/grammar-understanding-captures-vs-name/14783 Generally the best docs: http://manual.macromates.com/en/language_grammars.html - -# Dynamic Grammar - -> Warning : :warning: This feature is now legacy but has some good learning - -We used dynamic (code driven) grammar initially. Following are the lessons still worth sharing but we are using the CSON grammar now. - -I am using `atom` and `first-mate` interchangeably here. There isn't a documented way of creating a grammar from *code*. We found a hacky way by reading a *lot of source code*. Please look at `typeScriptGrammar.ts`. Basically you inherit from `Grammar` and let that do the heavy lifting. Then all you need is to return `AtomTokens` from `tokenizeLine`. The way the atom grammar works is that they will store the returned `ruleSet` for any line and call `tokenizeLine` for the next line passing in that `ruleSet`. As soon as you edit a line all the following lines are invalidated and `tokenizeLine` is called for them again. This works beautifully with the `ts.createClassifier` which is a quick syntactic classifier provided by the TS language service. It only depends on a `finalLexState` (e.g. did the previous line have a continuing multiline comment) and that is what we store in the `ruleSet`. - -**Warnings**: -* Atom is stingy about you calling its `createToken` in the *right order* so don't just call it unless you have the classification at exactly the right time. -* Atom doesn't want you to classify the BOM. It will give it to you as a part of the string, its up to you to carefully ignore it and don't call `createToken` for it. -* Do not mutate the `ruleSet` that is passed into you. Its for the previous line. Create your own `ruleSet` for your line! -* Also see [#159](https://github.com/TypeStrong/atom-typescript/issues/159) to see how editor settings (still using regex copied from language-javascript) + forcefully tokenizing empty lines plays with autoindent. - - diff --git a/docs/out.md b/docs/out.md deleted file mode 100644 index f9f42d230..000000000 --- a/docs/out.md +++ /dev/null @@ -1,104 +0,0 @@ -# `--out` is BAD -We do not support `--out` as we think its a bad idea for you to use because of the following reasons: - -* Runtime Errors -* Fast compile -* Global scope -* Hard to analyze -* Hard to scale -* `_references` -* Code reuse -* Multiple Targets -* Isolated Compile - -## Runtime Errors - -If your code depends on any form of js ordering you will get random errors at runtime. - -* **class inheritance can break at runtime.** - -Consider `foo.ts`: -```ts -class Foo { - -} -``` - -and a `bar.ts`: -```ts -class Bar extends Foo { - -} -``` - -If you fail to compile it in correct order e.g. perhaps alphabetically `tsc bar.ts foo.ts` the code will compile fine but error at runtime with `ReferenceError`. - -* **module splitting can fail at runtime.** - -Consider `foo.ts`: -```ts -module App { - export var foo = 123; -} -``` -And `bar.ts`: -```ts -module App { - export var bar = foo + 456; -} -``` - -If you fail to compile it in correct order e.g. perhaps alphabetically `tsc bar.ts foo.ts` the code will compile fine but *silently* fail at runtime with `bar` set to `NaN`. - -## Fast compile -If you use `--out` then single `.ts` files cannot be codegened into single `.js` files in isolation without unnecessary hacks. `--out` essentially forces a slower incremental build. - -Also source maps are positionally sensitive and run-length encoded so most of the map has to be rebuilt on a recompile if you use source maps (which you should!). At high-10s to 100s kloc combined it’s going to get slow. - -## Global Scope -Sure you can use name spaces but its still on `window` if you run it in the browser. Namespaces are just an unnecessary workaround. Also `/// ) | + ([(]\\s*(([)]\\s*:)|([_$[:alpha:]][_$[:alnum:]]*\\s*:)|(\\.\\.\\.) )) | + ([<]\\s*[_$[:alpha:]][_$[:alnum:]]*((\\s+extends\\s*[^=>])|(\\s*[,]))) | ((<([^<>]|\\<[^<>]+\\>)+>\\s*)?\\(([^()]|\\([^()]*\\))*\\)(\\s*:\\s*(.)*)?\\s*=>)) ) | (:\\s*( @@ -154,13 +153,7 @@ repository: end: "(?=$|[;,=}]|(\\s+(of|in)\\s+))" patterns: [ { - include: "#type-annotation" - } - { - include: "#string" - } - { - include: "#comment" + include: "#var-single-variable-type-annotation" } ] } @@ -171,6 +164,11 @@ repository: "1": name: "meta.definition.variable.ts variable.other.constant.ts" end: "(?=$|[;,=}]|(\\s+(of|in)\\s+))" + patterns: [ + { + include: "#var-single-variable-type-annotation" + } + ] } { name: "meta.var-single-variable.expr.ts" @@ -181,17 +179,23 @@ repository: end: "(?=$|[;,=}]|(\\s+(of|in)\\s+))" patterns: [ { - include: "#type-annotation" - } - { - include: "#string" - } - { - include: "#comment" + include: "#var-single-variable-type-annotation" } ] } ] + "var-single-variable-type-annotation": + patterns: [ + { + include: "#type-annotation" + } + { + include: "#string" + } + { + include: "#comment" + } + ] "destructuring-variable": patterns: [ { @@ -350,7 +354,6 @@ repository: } ] expression: - name: "meta.expression.ts" patterns: [ { comment: "Match Angular 2 Component html templates" @@ -381,10 +384,7 @@ repository: include: "#comment" } { - include: "#literal" - } - { - include: "#function-declaration" + include: "#function-expression" } { include: "#class-or-interface-declaration" @@ -410,6 +410,9 @@ repository: { include: "#function-call" } + { + include: "#literal" + } { include: "#support-objects" } @@ -440,14 +443,6 @@ repository: name: "keyword.control.flow.ts" match: "(?) | + ([(]\\s*(([)]\\s*:)|([_$[:alpha:]][_$[:alnum:]]*\\s*:)|(\\.\\.\\.) )) | + ([<]\\s*[_$[:alpha:]][_$[:alnum:]]*((\\s+extends\\s*[^=>])|(\\s*[,]))) | ((<([^<>]|\\<[^<>]+\\>)+>\\s*)?\\(([^()]|\\([^()]*\\))*\\)(\\s*:\\s*(.)*)?\\s*=>)) ) | (:\\s*( @@ -1094,7 +1096,7 @@ repository: name: "storage.type.ts" "7": name: "keyword.generator.asterisk.ts" - end: "(?=\\}|;|,)|(?<=\\})" + end: "(?=\\}|;|,|$)|(?<=\\})" patterns: [ { include: "#method-declaration-name" @@ -1111,36 +1113,10 @@ repository: { include: "#return-type" } - { - include: "#method-overload-declaration" - } { include: "#decl-block" } ] - "method-overload-declaration": - begin: "(?) | + ([(]\\s*(([)]\\s*:)|([_$[:alpha:]][_$[:alnum:]]*\\s*:)|(\\.\\.\\.) )) | + ([<]\\s*[_$[:alpha:]][_$[:alnum:]]*((\\s+extends\\s*[^=>])|(\\s*[,]))) | ((<([^<>]|\\<[^<>]+\\>)+>\\s*)?\\(([^()]|\\([^()]*\\))*\\)(\\s*:\\s*(.)*)?\\s*=>)) ) | (:\\s*( @@ -1535,7 +1526,7 @@ repository: beginCaptures: "1": name: "keyword.operator.type.annotation.ts" - end: "(?)\\s*(?=\\()" - end: "(?<=\\))" - patterns: [ - { - include: "#function-parameters" - } - ] - } { name: "meta.type.function.ts" begin: ''' @@ -1837,6 +1817,10 @@ repository: name: "storage.modifier.ts" match: "(?)" + } { include: "#type" } @@ -1845,14 +1829,30 @@ repository: } ] "variable-initializer": - begin: "(?]|\\<[^<>]+\\>)+>\\s*)?\\()" - end: "(?<=\\))(?!(\\.\\s*)?([_$[:alpha:]][_$[:alnum:]]*)\\s*(<([^<>]|\\<[^<>]+\\>)+>\\s*)?\\()" + begin: "(?=(([_$[:alpha:]][_$[:alnum:]]*\\s*\\.\\s*)*|(\\.\\s*)?)([_$[:alpha:]][_$[:alnum:]]*)\\s*(<([^<>]|\\<[^<>]+\\>)+>\\s*)?\\()" + end: "(?<=\\))(?!(([_$[:alpha:]][_$[:alnum:]]*\\s*\\.\\s*)*|(\\.\\s*)?)([_$[:alpha:]][_$[:alnum:]]*)\\s*(<([^<>]|\\<[^<>]+\\>)+>\\s*)?\\()" patterns: [ + { + include: "#literal" + } { include: "#support-objects" } + { + include: "#object-identifiers" + } { include: "#punctuation-accessor" } @@ -2319,29 +2318,15 @@ repository: identifiers: patterns: [ { - name: "support.class.ts" - match: "([_$[:alpha:]][_$[:alnum:]]*)(?=\\s*\\.\\s*prototype\\b(?!\\$))" - } - { - match: ''' - (?x)(\\.)\\s*(?: - ([[:upper:]][_$[:digit:][:upper:]]*) | - ([_$[:alpha:]][_$[:alnum:]]*) - )(?=\\s*\\.\\s*[_$[:alpha:]][_$[:alnum:]]*) - ''' - captures: - "1": - name: "punctuation.accessor.ts" - "2": - name: "variable.other.constant.object.property.ts" - "3": - name: "variable.other.object.property.ts" + include: "#object-identifiers" } { match: ''' (?x)(?:(\\.)\\s*)?([_$[:alpha:]][_$[:alnum:]]*)(?=\\s*=\\s*( (async\\s+)|(function\\s*[(<])|(function\\s+)| ([_$[:alpha:]][_$[:alnum:]]*\\s*=>)| + ([(]\\s*(([)]\\s*:)|([_$[:alpha:]][_$[:alnum:]]*\\s*:)|(\\.\\.\\.) )) | + ([<]\\s*[_$[:alpha:]][_$[:alnum:]]*((\\s+extends\\s*[^=>])|(\\s*[,]))) | ((<([^<>]|\\<[^<>]+\\>)+>\\s*)?\\(([^()]|\\([^()]*\\))*\\)(\\s*:\\s*(.)*)?\\s*=>))) ''' captures: @@ -2366,6 +2351,36 @@ repository: "2": name: "variable.other.property.ts" } + { + name: "variable.other.constant.ts" + match: "([[:upper:]][_$[:digit:][:upper:]]*)(?![_$[:alnum:]])" + } + { + name: "variable.other.readwrite.ts" + match: "[_$[:alpha:]][_$[:alnum:]]*" + } + ] + "object-identifiers": + patterns: [ + { + name: "support.class.ts" + match: "([_$[:alpha:]][_$[:alnum:]]*)(?=\\s*\\.\\s*prototype\\b(?!\\$))" + } + { + match: ''' + (?x)(\\.)\\s*(?: + ([[:upper:]][_$[:digit:][:upper:]]*) | + ([_$[:alpha:]][_$[:alnum:]]*) + )(?=\\s*\\.\\s*[_$[:alpha:]][_$[:alnum:]]*) + ''' + captures: + "1": + name: "punctuation.accessor.ts" + "2": + name: "variable.other.constant.object.property.ts" + "3": + name: "variable.other.object.property.ts" + } { match: ''' (?x)(?: @@ -2379,14 +2394,6 @@ repository: "2": name: "variable.other.object.ts" } - { - name: "variable.other.constant.ts" - match: "([[:upper:]][_$[:digit:][:upper:]]*)(?![_$[:alnum:]])" - } - { - name: "variable.other.readwrite.ts" - match: "[_$[:alpha:]][_$[:alnum:]]*" - } ] cast: name: "cast.expr.ts" @@ -2409,7 +2416,7 @@ repository: beginCaptures: "1": name: "keyword.operator.new.ts" - end: "(?<=\\))|(?=[;),]|$|((?)| + ([(]\\s*(([)]\\s*:)|([_$[:alpha:]][_$[:alnum:]]*\\s*:)|(\\.\\.\\.) )) | + ([<]\\s*[_$[:alpha:]][_$[:alnum:]]*((\\s+extends\\s*[^=>])|(\\s*[,]))) | ((<([^<>]|\\<[^<>]+\\>)+>\\s*)?\\(([^()]|\\([^()]*\\))*\\)(\\s*:\\s*(.)*)?\\s*=>)))) ''' beginCaptures: @@ -2522,6 +2531,14 @@ repository: name: "keyword.control.flow.ts" match: "(?)" @@ -2639,8 +2649,37 @@ repository: } { name: "meta.arrow.ts" - begin: "(?x)\\s*(?=(<([^<>]|\\<[^<>]+\\>)+>\\s*)?\\(([^()]|\\([^()]*\\))*\\)(\\s*:\\s*(.)*)?\\s*=>)" - end: "(?==>)" + begin: ''' + (?x) (?: + (? is on new line + ( + [(]\\s* + ( + ([)]\\s*:) | # (): + ([_$[:alpha:]][_$[:alnum:]]*\\s*:) | # [(]param: + (\\.\\.\\.) # [(]... + ) + ) | + ( + [<]\\s*[_$[:alpha:]][_$[:alnum:]]*\\s+extends\\s*[^=>] # < typeparam extends + ) | + # arrow function possible to detect only with => on same line + ( + (<([^<>]|\\<[^<>]+\\>)+>\\s*)? # typeparameters + \\(([^()]|\\([^()]*\\))*\\) # parameteres + (\\s*:\\s*(.)*)? # return type + \\s*=> # arrow operator + ) + ) + ) + ''' + beginCaptures: + "1": + name: "storage.modifier.async.ts" + end: "(?==>|\\{)" patterns: [ { include: "#comment" @@ -2679,8 +2718,24 @@ repository: beginCaptures: "1": name: "keyword.operator.type.annotation.ts" - end: "(?|;|//))" + end: "(?==>|\\{)" patterns: [ + { + name: "meta.object.type.ts" + begin: "(?<=:)\\s*(\\{)" + beginCaptures: + "1": + name: "punctuation.definition.block.ts" + end: "\\}" + endCaptures: + "0": + name: "punctuation.definition.block.ts" + patterns: [ + { + include: "#type-object-members" + } + ] + } { include: "#type-predicate-operator" } @@ -2751,7 +2806,7 @@ repository: regex: patterns: [ { - name: "string.regex.ts" + name: "string.regexp.ts" begin: "(?<=[=(:,\\[?+!]|return|case|=>|&&|\\|\\||\\*\\/)\\s*(/)(?![/*])(?=(?:[^/\\\\\\[]|\\\\.|\\[([^\\]\\\\]|\\\\.)+\\])+/(?![/*])[gimy]*(?!\\s*[a-zA-Z0-9_$]))" beginCaptures: "1": @@ -2769,7 +2824,7 @@ repository: ] } { - name: "string.regex.ts" + name: "string.regexp.ts" begin: "(?) | + ([(]\\s*(([)]\\s*:)|([_$[:alpha:]][_$[:alnum:]]*\\s*:)|(\\.\\.\\.) )) | + ([<]\\s*[_$[:alpha:]][_$[:alnum:]]*((\\s+extends\\s*[^=>])|(\\s*[,]))) | ((<([^<>]|\\<[^<>]+\\>)+>\\s*)?\\(([^()]|\\([^()]*\\))*\\)(\\s*:\\s*(.)*)?\\s*=>)) ) | (:\\s*( @@ -154,13 +153,7 @@ repository: end: "(?=$|[;,=}]|(\\s+(of|in)\\s+))" patterns: [ { - include: "#type-annotation" - } - { - include: "#string" - } - { - include: "#comment" + include: "#var-single-variable-type-annotation" } ] } @@ -171,6 +164,11 @@ repository: "1": name: "meta.definition.variable.tsx variable.other.constant.tsx" end: "(?=$|[;,=}]|(\\s+(of|in)\\s+))" + patterns: [ + { + include: "#var-single-variable-type-annotation" + } + ] } { name: "meta.var-single-variable.expr.tsx" @@ -181,17 +179,23 @@ repository: end: "(?=$|[;,=}]|(\\s+(of|in)\\s+))" patterns: [ { - include: "#type-annotation" - } - { - include: "#string" - } - { - include: "#comment" + include: "#var-single-variable-type-annotation" } ] } ] + "var-single-variable-type-annotation": + patterns: [ + { + include: "#type-annotation" + } + { + include: "#string" + } + { + include: "#comment" + } + ] "destructuring-variable": patterns: [ { @@ -350,7 +354,6 @@ repository: } ] expression: - name: "meta.expression.tsx" patterns: [ { comment: "Match Angular 2 Component html templates" @@ -384,10 +387,7 @@ repository: include: "#comment" } { - include: "#literal" - } - { - include: "#function-declaration" + include: "#function-expression" } { include: "#class-or-interface-declaration" @@ -413,6 +413,9 @@ repository: { include: "#function-call" } + { + include: "#literal" + } { include: "#support-objects" } @@ -443,14 +446,6 @@ repository: name: "keyword.control.flow.tsx" match: "(?) | + ([(]\\s*(([)]\\s*:)|([_$[:alpha:]][_$[:alnum:]]*\\s*:)|(\\.\\.\\.) )) | + ([<]\\s*[_$[:alpha:]][_$[:alnum:]]*((\\s+extends\\s*[^=>])|(\\s*[,]))) | ((<([^<>]|\\<[^<>]+\\>)+>\\s*)?\\(([^()]|\\([^()]*\\))*\\)(\\s*:\\s*(.)*)?\\s*=>)) ) | (:\\s*( @@ -1097,7 +1099,7 @@ repository: name: "storage.type.tsx" "7": name: "keyword.generator.asterisk.tsx" - end: "(?=\\}|;|,)|(?<=\\})" + end: "(?=\\}|;|,|$)|(?<=\\})" patterns: [ { include: "#method-declaration-name" @@ -1114,36 +1116,10 @@ repository: { include: "#return-type" } - { - include: "#method-overload-declaration" - } { include: "#decl-block" } ] - "method-overload-declaration": - begin: "(?) | + ([(]\\s*(([)]\\s*:)|([_$[:alpha:]][_$[:alnum:]]*\\s*:)|(\\.\\.\\.) )) | + ([<]\\s*[_$[:alpha:]][_$[:alnum:]]*((\\s+extends\\s*[^=>])|(\\s*[,]))) | ((<([^<>]|\\<[^<>]+\\>)+>\\s*)?\\(([^()]|\\([^()]*\\))*\\)(\\s*:\\s*(.)*)?\\s*=>)) ) | (:\\s*( @@ -1538,7 +1529,7 @@ repository: beginCaptures: "1": name: "keyword.operator.type.annotation.tsx" - end: "(?)\\s*(?=\\()" - end: "(?<=\\))" - patterns: [ - { - include: "#function-parameters" - } - ] - } { name: "meta.type.function.tsx" begin: ''' @@ -1840,6 +1820,10 @@ repository: name: "storage.modifier.tsx" match: "(?)" + } { include: "#type" } @@ -1848,14 +1832,30 @@ repository: } ] "variable-initializer": - begin: "(?]|\\<[^<>]+\\>)+>\\s*)?\\()" - end: "(?<=\\))(?!(\\.\\s*)?([_$[:alpha:]][_$[:alnum:]]*)\\s*(<([^<>]|\\<[^<>]+\\>)+>\\s*)?\\()" + begin: "(?=(([_$[:alpha:]][_$[:alnum:]]*\\s*\\.\\s*)*|(\\.\\s*)?)([_$[:alpha:]][_$[:alnum:]]*)\\s*(<([^<>]|\\<[^<>]+\\>)+>\\s*)?\\()" + end: "(?<=\\))(?!(([_$[:alpha:]][_$[:alnum:]]*\\s*\\.\\s*)*|(\\.\\s*)?)([_$[:alpha:]][_$[:alnum:]]*)\\s*(<([^<>]|\\<[^<>]+\\>)+>\\s*)?\\()" patterns: [ + { + include: "#literal" + } { include: "#support-objects" } + { + include: "#object-identifiers" + } { include: "#punctuation-accessor" } @@ -2322,29 +2321,15 @@ repository: identifiers: patterns: [ { - name: "support.class.tsx" - match: "([_$[:alpha:]][_$[:alnum:]]*)(?=\\s*\\.\\s*prototype\\b(?!\\$))" - } - { - match: ''' - (?x)(\\.)\\s*(?: - ([[:upper:]][_$[:digit:][:upper:]]*) | - ([_$[:alpha:]][_$[:alnum:]]*) - )(?=\\s*\\.\\s*[_$[:alpha:]][_$[:alnum:]]*) - ''' - captures: - "1": - name: "punctuation.accessor.tsx" - "2": - name: "variable.other.constant.object.property.tsx" - "3": - name: "variable.other.object.property.tsx" + include: "#object-identifiers" } { match: ''' (?x)(?:(\\.)\\s*)?([_$[:alpha:]][_$[:alnum:]]*)(?=\\s*=\\s*( (async\\s+)|(function\\s*[(<])|(function\\s+)| ([_$[:alpha:]][_$[:alnum:]]*\\s*=>)| + ([(]\\s*(([)]\\s*:)|([_$[:alpha:]][_$[:alnum:]]*\\s*:)|(\\.\\.\\.) )) | + ([<]\\s*[_$[:alpha:]][_$[:alnum:]]*((\\s+extends\\s*[^=>])|(\\s*[,]))) | ((<([^<>]|\\<[^<>]+\\>)+>\\s*)?\\(([^()]|\\([^()]*\\))*\\)(\\s*:\\s*(.)*)?\\s*=>))) ''' captures: @@ -2369,6 +2354,36 @@ repository: "2": name: "variable.other.property.tsx" } + { + name: "variable.other.constant.tsx" + match: "([[:upper:]][_$[:digit:][:upper:]]*)(?![_$[:alnum:]])" + } + { + name: "variable.other.readwrite.tsx" + match: "[_$[:alpha:]][_$[:alnum:]]*" + } + ] + "object-identifiers": + patterns: [ + { + name: "support.class.tsx" + match: "([_$[:alpha:]][_$[:alnum:]]*)(?=\\s*\\.\\s*prototype\\b(?!\\$))" + } + { + match: ''' + (?x)(\\.)\\s*(?: + ([[:upper:]][_$[:digit:][:upper:]]*) | + ([_$[:alpha:]][_$[:alnum:]]*) + )(?=\\s*\\.\\s*[_$[:alpha:]][_$[:alnum:]]*) + ''' + captures: + "1": + name: "punctuation.accessor.tsx" + "2": + name: "variable.other.constant.object.property.tsx" + "3": + name: "variable.other.object.property.tsx" + } { match: ''' (?x)(?: @@ -2382,14 +2397,6 @@ repository: "2": name: "variable.other.object.tsx" } - { - name: "variable.other.constant.tsx" - match: "([[:upper:]][_$[:digit:][:upper:]]*)(?![_$[:alnum:]])" - } - { - name: "variable.other.readwrite.tsx" - match: "[_$[:alpha:]][_$[:alnum:]]*" - } ] cast: patterns: [ @@ -2403,7 +2410,7 @@ repository: beginCaptures: "1": name: "keyword.operator.new.tsx" - end: "(?<=\\))|(?=[;),]|$|((?)| + ([(]\\s*(([)]\\s*:)|([_$[:alpha:]][_$[:alnum:]]*\\s*:)|(\\.\\.\\.) )) | + ([<]\\s*[_$[:alpha:]][_$[:alnum:]]*((\\s+extends\\s*[^=>])|(\\s*[,]))) | ((<([^<>]|\\<[^<>]+\\>)+>\\s*)?\\(([^()]|\\([^()]*\\))*\\)(\\s*:\\s*(.)*)?\\s*=>)))) ''' beginCaptures: @@ -2516,6 +2525,14 @@ repository: name: "keyword.control.flow.tsx" match: "(?)" @@ -2633,8 +2643,37 @@ repository: } { name: "meta.arrow.tsx" - begin: "(?x)\\s*(?=(<([^<>]|\\<[^<>]+\\>)+>\\s*)?\\(([^()]|\\([^()]*\\))*\\)(\\s*:\\s*(.)*)?\\s*=>)" - end: "(?==>)" + begin: ''' + (?x) (?: + (? is on new line + ( + [(]\\s* + ( + ([)]\\s*:) | # (): + ([_$[:alpha:]][_$[:alnum:]]*\\s*:) | # [(]param: + (\\.\\.\\.) # [(]... + ) + ) | + ( + [<]\\s*[_$[:alpha:]][_$[:alnum:]]*\\s+extends\\s*[^=>] # < typeparam extends + ) | + # arrow function possible to detect only with => on same line + ( + (<([^<>]|\\<[^<>]+\\>)+>\\s*)? # typeparameters + \\(([^()]|\\([^()]*\\))*\\) # parameteres + (\\s*:\\s*(.)*)? # return type + \\s*=> # arrow operator + ) + ) + ) + ''' + beginCaptures: + "1": + name: "storage.modifier.async.tsx" + end: "(?==>|\\{)" patterns: [ { include: "#comment" @@ -2673,8 +2712,24 @@ repository: beginCaptures: "1": name: "keyword.operator.type.annotation.tsx" - end: "(?|;|//))" + end: "(?==>|\\{)" patterns: [ + { + name: "meta.object.type.tsx" + begin: "(?<=:)\\s*(\\{)" + beginCaptures: + "1": + name: "punctuation.definition.block.tsx" + end: "\\}" + endCaptures: + "0": + name: "punctuation.definition.block.tsx" + patterns: [ + { + include: "#type-object-members" + } + ] + } { include: "#type-predicate-operator" } @@ -2745,7 +2800,7 @@ repository: regex: patterns: [ { - name: "string.regex.tsx" + name: "string.regexp.tsx" begin: "(?<=[=(:,\\[?+!]|return|case|=>|&&|\\|\\||\\*\\/)\\s*(/)(?![/*])(?=(?:[^/\\\\\\[]|\\\\.|\\[([^\\]\\\\]|\\\\.)+\\])+/(?![/*])[gimy]*(?!\\s*[a-zA-Z0-9_$]))" beginCaptures: "1": @@ -2763,7 +2818,7 @@ repository: ] } { - name: "string.regex.tsx" + name: "string.regexp.tsx" begin: "(? = new Map() + + constructor(private onPendingChange: (pending: string[]) => void) {} + + add(seq: number, command: string) { + return new Promise((resolve, reject) => { + this.callbacks.set(seq, { + name: command, + resolve, + reject, + started: Date.now() + }) + + this.onPendingChange(this.pending()) + }) + } + + // pending returns names of requests waiting for a response + pending(): string[] { + const pending: string[] = [] + + for (const {name} of this.callbacks.values()) { + pending.push(name) + } + + return pending + } + + rejectAll(error: any) { + for (const {reject} of this.callbacks.values()) { + reject(error) + } + + this.callbacks.clear() + this.onPendingChange(this.pending()) + } + + // Remove and return a Request object, if one exists + remove(seq: number): Request | undefined { + const req = this.callbacks.get(seq) + this.callbacks.delete(seq) + if (req) { + this.onPendingChange(this.pending()) + } + return req + } +} diff --git a/lib/client/client.ts b/lib/client/client.ts new file mode 100644 index 000000000..19c7a9dda --- /dev/null +++ b/lib/client/client.ts @@ -0,0 +1,293 @@ +import * as protocol from "typescript/lib/protocol" +import {BufferedNodeProcess, BufferedProcess} from "atom" +import {Callbacks} from "./callbacks" +import {ChildProcess} from "child_process" +import {EventEmitter} from "events" +import {Transform, Readable} from "stream" +import byline = require("byline") + +// Set this to true to start tsserver with node --inspect +const INSPECT_TSSERVER = false + +export const CommandWithResponse = new Set([ + "compileOnSaveAffectedFileList", + "compileOnSaveEmitFile", + "completionEntryDetails", + "completions", + "configure", + "definition", + "format", + "occurrences", + "projectInfo", + "quickinfo", + "references", + "reload", + "rename", +]) + +export class TypescriptServiceClient { + + /** Callbacks that are waiting for responses */ + callbacks: Callbacks + + private events = new EventEmitter() + private seq = 0 + + /** The tsserver child process */ + server: ChildProcess + + /** Promise that resolves when the server is ready to accept requests */ + serverPromise?: Promise + + /** Extra args passed to the tsserver executable */ + readonly tsServerArgs: string[] = [] + + constructor(public tsServerPath: string, public version: string) { + this.callbacks = new Callbacks(this.emitPendingRequests) + } + + executeChange(args: protocol.ChangeRequestArgs): Promise { + return this.execute("change", args) + } + executeClose(args: protocol.FileRequestArgs): Promise { + return this.execute("close", args) + } + executeCompileOnSaveAffectedFileList(args: protocol.FileRequestArgs): Promise { + return this.execute("compileOnSaveAffectedFileList", args) + } + executeCompileOnSaveEmitFile(args: protocol.CompileOnSaveEmitFileRequestArgs): Promise { + return this.execute("compileOnSaveEmitFile", args) + } + executeCompletions(args: protocol.CompletionsRequestArgs): Promise { + return this.execute("completions", args) + } + executeCompletionDetails(args: protocol.CompletionDetailsRequestArgs): Promise { + return this.execute("completionEntryDetails", args) + } + executeConfigure(args: protocol.ConfigureRequestArguments): Promise { + return this.execute("configure", args) + } + executeDefinition(args: protocol.FileLocationRequestArgs): Promise { + return this.execute("definition", args) + } + executeFormat(args: protocol.FormatRequestArgs): Promise { + return this.execute("format", args) + } + executeGetErr(args: protocol.GeterrRequestArgs): Promise { + return this.execute("geterr", args) + } + executeGetErrForProject(args: protocol.GeterrForProjectRequestArgs): Promise { + return this.execute("geterrForProject", args) + } + executeOccurances(args: protocol.FileLocationRequestArgs): Promise { + return this.execute("occurrences", args) + } + executeOpen(args: protocol.OpenRequestArgs): Promise { + return this.execute("open", args) + } + executeProjectInfo(args: protocol.ProjectInfoRequestArgs): Promise { + return this.execute("projectInfo", args) + } + executeQuickInfo(args: protocol.FileLocationRequestArgs): Promise { + return this.execute("quickinfo", args) + } + executeReferences(args: protocol.FileLocationRequestArgs): Promise { + return this.execute("references", args) + } + executeReload(args: protocol.ReloadRequestArgs): Promise { + return this.execute("reload", args) + } + executeRename(args: protocol.RenameRequestArgs): Promise { + return this.execute("rename", args) + } + executeSaveTo(args: protocol.SavetoRequestArgs) { + return this.execute("saveto", args) + } + + private async execute(command: string, args: any) { + if (!this.serverPromise) { + throw new Error("Server is not running") + } + + return this.sendRequest(await this.serverPromise, command, args, CommandWithResponse.has(command)) + } + + /** Adds an event listener for tsserver or other events. Returns an unsubscribe function */ + on(name: "configFileDiag", listener: (result: protocol.DiagnosticEventBody) => any): Function + on(name: "pendingRequestsChange", listener: (requests: string[]) => any): Function + on(name: "semanticDiag", listener: (result: protocol.DiagnosticEventBody) => any): Function + on(name: "syntaxDiag", listener: (result: protocol.DiagnosticEventBody) => any): Function + on(name: string, listener: (result: any) => any): Function { + this.events.on(name, listener) + + return () => { + this.events.removeListener(name, listener) + } + } + + private emitPendingRequests = (pending: string[]) => { + this.events.emit("pendingRequestsChange", pending) + } + + private onMessage = (res: protocol.Response | protocol.Event) => { + if (isResponse(res)) { + const req = this.callbacks.remove(res.request_seq) + if (req) { + if (window.atom_typescript_debug) { + console.log("received response for", res.command, "in", Date.now() - req.started, "ms", "with data", res.body) + } + + if (res.success) { + req.resolve(res) + } else { + req.reject(new Error(res.message)) + } + } else { + console.warn("unexpected response:", res) + } + } else if (isEvent(res)) { + if (window.atom_typescript_debug) { + console.log("received event", res) + } + + this.events.emit(res.event, res.body) + } + } + + private sendRequest(cp: ChildProcess, command: string, args: any, expectResponse: true): Promise + private sendRequest(cp: ChildProcess, command: string, args: any, expectResponse: false): undefined + private sendRequest(cp: ChildProcess, command: string, args: any, expectResponse: boolean): Promise | undefined + private sendRequest(cp: ChildProcess, command: string, args: any, expectResponse: boolean): Promise | undefined { + + const req = { + seq: this.seq++, + command, + arguments: args + } + + if (window.atom_typescript_debug) { + console.log("sending request", command, "with args", args) + } + + setImmediate(() => { + try { + cp.stdin.write(JSON.stringify(req) + "\n") + } catch (error) { + const callback = this.callbacks.remove(req.seq) + if (callback) { + callback.reject(error) + } else { + console.error(error) + } + } + }) + + if (expectResponse) { + return this.callbacks.add(req.seq, command) + } + } + + startServer() { + if (!this.serverPromise) { + let lastStderrOutput: string + let reject: (err: Error) => void + + const exitHandler = (result: Error | number) => { + const err = typeof result === "number" ? + new Error("exited with code: " + result) : result + + console.error("tsserver: ", err) + this.callbacks.rejectAll(err) + reject(err) + this.serverPromise = undefined + + setImmediate(() => { + let detail = err && err.stack || "" + + if (lastStderrOutput) { + detail = "Last output from tsserver:\n" + lastStderrOutput + "\n \n" + detail + } + + atom.notifications.addError("Typescript quit unexpectedly", { + detail, + dismissable: true, + }) + }) + } + + return this.serverPromise = new Promise((resolve, _reject) => { + reject = _reject + + if (window.atom_typescript_debug) { + console.log("starting", this.tsServerPath) + } + + const cp = startServer(this.tsServerPath, this.tsServerArgs) + + cp.once("error", exitHandler) + cp.once("exit", exitHandler) + + // Pipe both stdout and stderr appropriately + messageStream(cp.stdout).on("data", this.onMessage) + cp.stderr.on("data", data => { + console.warn("tsserver stderr:", lastStderrOutput = data.toString()) + }) + + // We send an unknown command to verify that the server is working. + this.sendRequest(cp, "ping", null, true).then(res => resolve(cp), err => resolve(cp)) + }) + + } else { + throw new Error(`Server already started: ${this.tsServerPath}`) + } + } +} + +function startServer(tsServerPath: string, tsServerArgs: string[]): ChildProcess { + if (INSPECT_TSSERVER) { + return new BufferedProcess({ + command: "node", + args: ["--inspect", tsServerPath].concat(tsServerArgs), + }).process as any + } else { + return new BufferedNodeProcess({ + command: tsServerPath, + args: tsServerArgs + }).process as any + } +} + +function isEvent(res: protocol.Response | protocol.Event): res is protocol.Event { + return res.type === "event" +} + +function isResponse(res: protocol.Response | protocol.Event): res is protocol.Response { + return res.type === "response" +} + +function messageStream(input: Readable) { + return input.pipe(byline()).pipe(new MessageStream()) +} + +/** Helper to parse the tsserver output stream to a message stream */ +class MessageStream extends Transform { + constructor() { + super({objectMode: true}) + } + + _transform(buf: Buffer, encoding: string, callback: Function) { + const line = buf.toString() + + try { + if (line.startsWith("{")) { + this.push(JSON.parse(line)) + } else if (!line.startsWith("Content-Length:")) { + console.warn(line) + } + } catch (error) { + console.error("client: failed to parse: ", line) + } finally { + callback(null) + } + } +} diff --git a/lib/client/clientResolver.ts b/lib/client/clientResolver.ts new file mode 100644 index 000000000..958f13e70 --- /dev/null +++ b/lib/client/clientResolver.ts @@ -0,0 +1,111 @@ +import {TypescriptServiceClient as Client} from "./client" +import * as events from "events" +import * as path from "path" +import {sync as resolveSync} from "resolve" +import {Diagnostic, DiagnosticEventBody, ConfigFileDiagnosticEventBody} from "typescript/lib/protocol" + +type DiagnosticTypes = "configFileDiag" | "semanticDiag" | "syntaxDiag" + +interface DiagnosticsPayload { + diagnostics: Diagnostic[] + filePath: string, + serverPath: string, + type: DiagnosticTypes, +} + +interface Server { + version: string + serverPath: string +} + +const defaultServer: Server = { + serverPath: require.resolve("typescript/bin/tsserver"), + version: require("typescript").version +} + +/** + * ClientResolver takes care of finding the correct tsserver for a source file based on how a + * require("typescript") from the same source file would resolve. + */ +export class ClientResolver extends events.EventEmitter { + + clients: { + [tsServerPath: string]: { + client: Client, + pending: string[], + } + } = {} + + // This is just here so Typescript can infer the types of the callbacks when using "on" method + on(event: "diagnostics", callback: (result: DiagnosticsPayload) => any): this + on(event: "pendingRequestsChange", callback: Function): this + on(event: string, callback: Function): this { + return super.on(event, callback) + } + + get(filePath: string): Promise { + return resolveServer(filePath) + .catch(() => defaultServer) + .then(({serverPath, version}) => { + if (this.clients[serverPath]) { + return this.clients[serverPath].client + } + + const entry = this.addClient(serverPath, new Client(serverPath, version)) + + entry.client.startServer() + + entry.client.on("pendingRequestsChange", pending => { + entry.pending = pending + this.emit("pendingRequestsChange") + }) + + const diagnosticHandler = (type: string, result: DiagnosticEventBody | ConfigFileDiagnosticEventBody) => { + const filePath = isConfDiagBody(result) ? result.configFile : result.file + + if (filePath) { + this.emit("diagnostics", { + type, + serverPath, + filePath, + diagnostics: result.diagnostics + }) + } + } + + entry.client.on("configFileDiag", diagnosticHandler.bind(this, "configFileDiag")) + entry.client.on("semanticDiag", diagnosticHandler.bind(this, "semanticDiag")) + entry.client.on("syntaxDiag", diagnosticHandler.bind(this, "syntaxDiag")) + + return entry.client + }) + } + + addClient(serverPath: string, client: Client) { + this.clients[serverPath] = { + client, + pending: [], + } + + return this.clients[serverPath] + } +} + +export function resolveServer(sourcePath: string): Promise { + const basedir = path.dirname(sourcePath) + + return Promise.resolve().then(() => { + const resolvedPath = resolveSync("typescript/bin/tsserver", {basedir}) + const packagePath = path.resolve(resolvedPath, "../../package.json") + const version = require(packagePath).version + + return { + version, + serverPath: resolvedPath + } + }) +} + +function isConfDiagBody(body: any): body is ConfigFileDiagnosticEventBody { + return body && body.triggerFile && body.configFile +} diff --git a/lib/globals.ts b/lib/globals.ts deleted file mode 100644 index de4e878ea..000000000 --- a/lib/globals.ts +++ /dev/null @@ -1,192 +0,0 @@ -/// -/// - -// From brackets plugin -/// -/// -/// -/// - -/// -/// - -/** Utility function to print stack trace from whereever */ -declare function stack(); -declare module NodeJS { - export interface Global { - stack: any; - ts: any; - } -} - -interface Function { - name?: string; // exists for named function on node / atom / "good" browsers ;) -} - -interface Error { - details?: any; // Really useful to have for debugging -} - -// escape-html -declare module 'escape-html' { - function escape(html: string): string; - export = escape; -} - -declare module 'detect-indent' { - function detectIndent (string: string): { amount: number; type?: string; indent: string }; - export = detectIndent; -} - -declare module 'detect-newline' { - function detectNewline (string: string): string; - export = detectNewline; -} - -declare module 'xtend' { - function extend (dest: T, src: U): T & U; - export = extend; -} - -declare module 'atom-space-pen-views' { - import atom = require('atom'); - export class SelectListView extends atom.SelectListView { } - export class ScrollView extends atom.ScrollView { } - export class View extends atom.View { } - export var $: JQueryStatic; -} - -declare module 'basarat-text-buffer' { - var ctor: { - new (content: string): TextBuffer.ITextBuffer; - }; - export = ctor; -} - -interface EmitOutput { - sourceFileName: string; - outputFiles: string[]; - success: boolean; - errors: CodeError[]; - emitError: boolean; -} - -interface BuildOutput { - outputs: EmitOutput[]; - counts: { - inputFiles: number; - outputFiles: number; - errors: number; - emitErrors: number; - } -} - -interface BuildUpdate { - builtCount: number; - totalCount: number; - errorCount: number; - firstError: boolean; - filePath: string; - errorsInFile: CodeError[]; -} - -interface CodeError { - filePath: string; - startPos: EditorPosition; - endPos: EditorPosition; - message: string; - preview: string; -} - -interface EditorPosition { - line: number; - col: number; -} - -interface CodeEdit { - start: EditorPosition; - end: EditorPosition; - newText: string; -} - -/** Interfaces used by GotoHistory feature */ -interface GotoPosition { - filePath: string; - line: number; - col: number; -} -interface TabWithGotoPositions { - lastPosition?: GotoPosition; - members: GotoPosition[]; -} - -/** Interfaces needed for file symbols view */ -interface NavigationBarItem { - text: string; - kind: string; - kindModifiers: string; - position: EditorPosition; - indent: number; - bolded: boolean; - grayed: boolean; -} -/** for project symbols view */ -interface NavigateToItem { - name: string; - kind: string; - filePath: string; - position: EditorPosition; - fileName: string; -} - -/** - * used by semantic view - */ -interface SemanticTreeNode { - text: string; - kind: string; - kindModifiers: string; - start: EditorPosition; - end: EditorPosition; - subNodes: SemanticTreeNode[]; -} - -interface ReferenceDetails { - filePath: string; - position: EditorPosition - preview: string; -} - -/** Used by AST display */ -interface NodeDisplay { - kind: string; - children: NodeDisplay[]; - - pos: number; - end: number; - - /** Represents how many parents it has */ - depth: number; - /** If we had a flat structure this is where this item would belong */ - nodeIndex: number; - - /** Key Details I understand */ - details?: any; - - /** Best attempt serialization of original node - * I also remove `parent` - */ - rawJson: any; -} - -/** Used by Dependency display */ -interface FileDependency { - sourcePath: string; - targetPath: string; -} - -/** Provided by the atom team */ -interface String { - startsWith(str: string): boolean; - endsWith(str: string): boolean; -} diff --git a/lib/hyperclickProvider.ts b/lib/hyperclickProvider.ts deleted file mode 100644 index d47220e43..000000000 --- a/lib/hyperclickProvider.ts +++ /dev/null @@ -1,35 +0,0 @@ -import * as parent from "./worker/parent"; -import * as atomUtils from "./main/atom/atomUtils"; -import {Set} from "immutable"; - -const TS_GRAMMARS = Set(["source.ts", "source.tsx"]); - -export let providerName = "typescript-hyperclick-provider"; - -export let wordRegExp = /([A-Za-z0-9_])+|['"`](\\.|[^'"`\\\\])*['"`]/g; - -export function getSuggestionForWord(textEditor: AtomCore.IEditor, text: string, range: TextBuffer.IRange) { - if (!TS_GRAMMARS.has(textEditor.getGrammar().scopeName)) { - return null; - } - - return { - range: range, - callback() { - let filePathPosition = { - filePath: textEditor.getPath(), - position: atomUtils.getEditorPositionForBufferPosition(textEditor, range.start) - }; - - parent.getDefinitionsAtPosition(filePathPosition).then((res) => { - if (res.definitions.length > 0) { - let definition = res.definitions[0]; - atom.workspace.open(definition.filePath, { - initialLine: definition.position.line, - initialColumn: definition.position.col - }); - } - }); - } - }; -} diff --git a/lib/linter.ts b/lib/linter.ts deleted file mode 100644 index 9f3f2e249..000000000 --- a/lib/linter.ts +++ /dev/null @@ -1,52 +0,0 @@ -// This file is only called from linter -// See : https://github.com/AtomLinter/Linter/issues/337 - -///ts:import=utils -import utils = require('./main/lang/utils'); ///ts:import:generated -///ts:import=parent -import parent = require('./worker/parent'); ///ts:import:generated - -import fs = require('fs'); -import {Range} from "atom"; - -interface LinterMessage { - type: string, // "Error" or "Warning" - text?: string, - html?: string, - filePath?: string, - range?: TextBuffer.IRange, - // trace?: Array // We don't care about this so I have this commented out -} - -export var provider = { - name: 'TS', - grammarScopes: ['source.ts', 'source.tsx'], - scope: 'file', // # or 'project' - lintOnFly: true, // # must be false for scope: 'project' - lint: (textEditor: AtomCore.IEditor): Promise => { - - // We do not support files not on disk - if (!textEditor.buffer.file - || !textEditor.buffer.file.path - || !fs.existsSync(textEditor.buffer.file.path)) return Promise.resolve([]); - - var filePath = textEditor.buffer.file.path; - - return parent.errorsForFile({ filePath: filePath }) - .then((resp) => { - var linterErrors: LinterMessage[] = resp.errors.map((err) => ({ - type: "Error", - filePath, - text: err.message, - range: new Range([err.startPos.line, err.startPos.col], [err.endPos.line, err.endPos.col]), - })); - return linterErrors; - }) - .catch((error) => { - /** - * We catch these errors as the linter will do a full blown notification message on error - */ - return []; - }); - } -} diff --git a/lib/main/atom/atomConfig.ts b/lib/main/atom/atomConfig.ts deleted file mode 100644 index 413f52813..000000000 --- a/lib/main/atom/atomConfig.ts +++ /dev/null @@ -1,46 +0,0 @@ -import {getName} from "../lang/utils"; - -// Documentation https://atom.io/docs/api/v0.177.0/Config and http://json-schema.org/examples.html -// To add a new setting you need to add to -// schema -// getter/setter - -var packageName = 'atom-typescript'; -function getConfig(nameLambda: () => any): T { - return atom.config.get(packageName + '.' + getName(nameLambda)); -} -function setConfig(nameLambda: () => any, value: T): T { - return atom.config.set(packageName + '.' + getName(nameLambda), value); -} - -class Config { - schema = { - debugAtomTs: { - title: 'Debug: Atom-TypeScript. Please do not use.', - type: 'boolean', - default: false - }, - preferredQuoteCharacter: { - title: 'Preferred quote character', - type: 'string', - default: 'none' - }, - typescriptServices: { - title: 'Full path (including file name) to a custom `typescriptServices.js`', - type: 'string', - default: '' - }, - showSemanticView: { - title: 'Show semantic view', - type: 'boolean', - default: false - } - } - get debugAtomTs() { return getConfig(() => this.schema.debugAtomTs) } - get preferredQuoteCharacter() { return getConfig(() => this.schema.preferredQuoteCharacter) } - get typescriptServices() { return getConfig(() => this.schema.typescriptServices) } - get showSemanticView() { return getConfig(() => this.schema.showSemanticView) } - set showSemanticView(value: boolean) { setConfig(() => this.schema.showSemanticView, value) } -} -var config = new Config(); -export = config; diff --git a/lib/main/atom/autoCompleteProvider.ts b/lib/main/atom/autoCompleteProvider.ts index 702224de5..b04f8cd08 100644 --- a/lib/main/atom/autoCompleteProvider.ts +++ b/lib/main/atom/autoCompleteProvider.ts @@ -1,200 +1,211 @@ -/// - // more: https://github.com/atom-community/autocomplete-plus/wiki/Provider-API +import {ClientResolver} from "../../client/clientResolver" +import {kindToType, FileLocationQuery} from "./utils" +import {Provider, RequestOptions, Suggestion} from "../../typings/autocomplete" +import {TypescriptBuffer} from "../typescriptBuffer" +import {TypescriptServiceClient} from "../../client/client" +import * as Atom from "atom" +import * as fuzzaldrin from "fuzzaldrin" + +const importPathScopes = ["meta.import", "meta.import-equals", "triple-slash-directive"] + +type SuggestionWithDetails = Suggestion & { + details?: protocol.CompletionEntryDetails +} -///ts:import=parent -import parent = require('../../worker/parent'); ///ts:import:generated -///ts:import=atomConfig -import atomConfig = require('./atomConfig'); ///ts:import:generated -import fs = require('fs'); -///ts:import=atomUtils -import atomUtils = require('./atomUtils'); ///ts:import:generated -import escape = require('escape-html'); - -var fuzzaldrin = require('fuzzaldrin'); -var CSON = require("season"); - -declare module autocompleteplus { - /** What gets passed into the handler */ - export interface RequestOptions { - editor: AtomCore.IEditor; - bufferPosition: TextBuffer.IPoint; // the position of the cursor - prefix: string; - scopeDescriptor: { scopes: string[] }; - } +type Options = { + getTypescriptBuffer: (filePath: string) => Promise<{ + buffer: TypescriptBuffer + isOpen: boolean + }> +} - /** The suggestion */ - export interface Suggestion { - //Either text or snippet is required +export class AutocompleteProvider implements Provider { + selector = ".source.ts, .source.tsx" - text?: string; - snippet?: string; + disableForSelector = ".comment" - replacementPrefix?: string; + inclusionPriority = 3 + suggestionPriority = 3 + excludeLowerPriority = false - rightLabel?: string; - rightLabelHTML?: string; - leftLabel?: string; - type: string; - description?: string; - } + private clientResolver: ClientResolver + private lastSuggestions: { + // Client used to get the suggestions + client: TypescriptServiceClient - /** What the provider needs to implement */ - export interface Provider { - inclusionPriority?: number; - excludeLowerPriority?: boolean; - suggestionPriority?: number; - selector: string; - disableForSelector?: string; - getSuggestions: (options: RequestOptions) => Promise; - onDidInsertSuggestion?: (args: { editor: AtomCore.IEditor; triggerPosition: TextBuffer.IPoint; suggestion: Suggestion }) => any; - } -} + // File and position for the suggestions + location: FileLocationQuery -var explicitlyTriggered = false; -export function triggerAutocompletePlus() { - atom.commands.dispatch( - atom.views.getView(atom.workspace.getActiveTextEditor()), - 'autocomplete-plus:activate'); - explicitlyTriggered = true; -} + // Prefix used + prefix: string -// the structure stored in the CSON snippet file -interface SnippetDescriptor { - prefix: string; - body: string; -} -interface SnippetsContianer { - [name: string]: SnippetDescriptor; -} + // The completions that were returned for the position + suggestions: SuggestionWithDetails[] + } + + private opts: Options -function getModuleAutocompleteType(scopes: string[]): { - isReference: boolean, - isRequire: boolean, // this only matches: import hello = require("^cursor") and not require("^") - isImport: boolean // ES6 import: import hello from "^cursor" -} { - function has(match: string): boolean { - return scopes.some(scope => scope.indexOf(match) !== -1) + constructor(clientResolver: ClientResolver, opts: Options) { + this.clientResolver = clientResolver + this.opts = opts } - let isString = has('string.quoted') + // Try to reuse the last completions we got from tsserver if they're for the same position. + async getSuggestionsWithCache( + prefix: string, + location: FileLocationQuery, + activatedManually: boolean, + ): Promise { + if (this.lastSuggestions && !activatedManually) { + const lastLoc = this.lastSuggestions.location + const lastCol = getNormalizedCol(this.lastSuggestions.prefix, lastLoc.offset) + const thisCol = getNormalizedCol(prefix, location.offset) + + if (lastLoc.file === location.file && lastLoc.line == location.line && lastCol === thisCol) { + if (this.lastSuggestions.suggestions.length !== 0) { + return this.lastSuggestions.suggestions + } + } + } - return { - isReference: has('reference.path.string.quoted') || has('amd.path.string.quoted'), - isRequire: has('meta.import-equals.external') && isString, - isImport: has('meta.import') && isString + const client = await this.clientResolver.get(location.file) + const completions = await client.executeCompletions({prefix, ...location}) + + const suggestions = completions.body!.map(entry => ({ + text: entry.name, + leftLabel: entry.kind, + type: kindToType(entry.kind), + })) + + this.lastSuggestions = { + client, + location, + prefix, + suggestions, + } + + return suggestions } -} -export var provider: autocompleteplus.Provider = { - selector: '.source.ts, .source.tsx', - inclusionPriority: 3, - suggestionPriority: 3, - excludeLowerPriority: false, - getSuggestions: (options: autocompleteplus.RequestOptions): Promise=> { + async getSuggestions(opts: RequestOptions): Promise { + const location = getLocationQuery(opts) + const {prefix} = opts - var filePath = options.editor.getPath(); + if (!location.file) { + return [] + } - // We refuse to work on files that are not on disk. - if (!filePath) return Promise.resolve([]); - if (!fs.existsSync(filePath)) return Promise.resolve([]); + // Don't show autocomplete if the previous character was a non word character except "." + const lastChar = getLastNonWhitespaceChar(opts.editor.buffer, opts.bufferPosition) + if (lastChar && !opts.activatedManually) { + if (/\W/i.test(lastChar) && lastChar !== ".") { + return [] + } + } - var {isReference, isRequire, isImport} = getModuleAutocompleteType(options.scopeDescriptor.scopes) + // Don't show autocomplete if we're in a string.template and not in a template expression + if (containsScope(opts.scopeDescriptor.scopes, "string.template.") + && !containsScope(opts.scopeDescriptor.scopes, "template.expression.")) { + return [] + } - // For file path completions - if (isReference || isRequire || isImport) { - return parent.getRelativePathsInProject({ filePath, prefix: options.prefix, includeExternalModules: isReference }) - .then((resp) => { + // Don't show autocomplete if we're in a string and it's not an import path + if (containsScope(opts.scopeDescriptor.scopes, "string.quoted.")) { + if (!importPathScopes.some(scope => containsScope(opts.scopeDescriptor.scopes, scope))) { + return [] + } + } - var range = options.editor.bufferRangeForScopeAtCursor(".string.quoted") - var cursor = options.editor.getCursorBufferPosition() + // Flush any pending changes for this buffer to get up to date completions + const {buffer} = await this.opts.getTypescriptBuffer(location.file) + await buffer.flush() - // Check if we're in a string and if the cursor is at the end of it. Bail otherwise - if (!range || cursor.column !== range.end.column-1) { - return [] - } + try { + var suggestions = await this.getSuggestionsWithCache(prefix, location, opts.activatedManually) + } catch (error) { + return [] + } - var content = options.editor.getTextInBufferRange(range).replace(/^['"]|['"]$/g, "") + const alphaPrefix = prefix.replace(/\W/g, "") + if (alphaPrefix !== "") { + suggestions = fuzzaldrin.filter(suggestions, alphaPrefix, {key: "text"}) + } - return resp.files.map(file => { - var relativePath = file.relativePath; + // Get additional details for the first few suggestions + await this.getAdditionalDetails(suggestions.slice(0, 10), location) - /** Optionally customize this in future */ - var suggestionText = relativePath; + const trimmed = prefix.trim() - var suggestion: autocompleteplus.Suggestion = { - text: suggestionText, - replacementPrefix: content, - rightLabelHTML: '' + file.name + '', - type: 'import' - }; + return suggestions.map(suggestion => ({ + replacementPrefix: getReplacementPrefix(prefix, trimmed, suggestion.text!), + ...suggestion + })) + } - return suggestion; - }); - }); - } - else { - - // if explicitly triggered reset the explicit nature - if (explicitlyTriggered) { - explicitlyTriggered = false; - } - else { // else in special cases for automatic triggering refuse to provide completions - const prefix = options.prefix.trim() - - if (prefix === '' || prefix === ';' || prefix === '{') { - return Promise.resolve([]); - } - } - - var position = atomUtils.getEditorPositionForBufferPosition(options.editor, options.bufferPosition); - - var promisedSuggestions: Promise - = parent.getCompletionsAtPosition({ - filePath: filePath, - position: position, - prefix: options.prefix, - }) - .then((resp) => { - - var completionList = resp.completions; - var suggestions = completionList.map((c): autocompleteplus.Suggestion => { - - if (c.snippet) // currently only function completions are snippet - { - return { - snippet: c.snippet, - replacementPrefix: '', - rightLabel: 'signature', - type: 'snippet', - }; - } - else { - var prefix = options.prefix; - // If the completion is $foo - // The prefix from acp is actually only `foo` - // But the var is $foo - // => so we would potentially end up replacing $foo with $$foo - // Fix that: - if (c.name && c.name.startsWith('$')) { - prefix = "$" + prefix; - } - - return { - text: c.name, - replacementPrefix: resp.endsInPunctuation ? '' : prefix.trim(), - rightLabel: c.display, - leftLabel: c.kind, - type: atomUtils.kindToType(c.kind), - description: c.comment, - }; - } - }); - - return suggestions; - }); - - return promisedSuggestions; + async getAdditionalDetails(suggestions: SuggestionWithDetails[], location: FileLocationQuery) { + if (suggestions.some(s => !s.details)) { + const details = await this.lastSuggestions.client.executeCompletionDetails({ + entryNames: suggestions.map(s => s.text!), + ...location + }) + + details.body!.forEach((detail, i) => { + const suggestion = suggestions[i] + + suggestion.details = detail + suggestion.rightLabel = detail.displayParts.map(d => d.text).join("") + + if (detail.documentation) { + suggestion.description = detail.documentation.map(d => d.text).join(" ") } - }, + }) + } + } +} + +// Decide what needs to be replaced in the editor buffer when inserting the completion +function getReplacementPrefix(prefix: string, trimmed: string, replacement: string): string { + if (trimmed === "." || trimmed === "{" || prefix === " ") { + return "" + } else if (replacement.startsWith("$")) { + return "$" + prefix + } else { + return prefix + } +} + +// When the user types each character in ".hello", we want to normalize the column such that it's +// the same for every invocation of the getSuggestions. In this case, it would be right after "." +function getNormalizedCol(prefix: string, col: number): number { + const length = prefix === "." ? 0 : prefix.length + return col - length +} + +function getLocationQuery(opts: RequestOptions): FileLocationQuery { + return { + file: opts.editor.getPath(), + line: opts.bufferPosition.row+1, + offset: opts.bufferPosition.column+1 + } +} + +function getLastNonWhitespaceChar(buffer: TextBuffer.ITextBuffer, pos: TextBuffer.IPoint): string | undefined { + let lastChar: string | undefined = undefined + const range = new Atom.Range([0,0], pos) + buffer.backwardsScanInRange(/\S/, range, ({matchText, stop}: {matchText: string, stop: () => void}) => { + lastChar = matchText + stop() + }) + return lastChar +} + +function containsScope(scopes: string[], matchScope: string): boolean { + for (const scope of scopes) { + if (scope.includes(matchScope)) { + return true + } + } + + return false } diff --git a/lib/main/atom/buildView.ts b/lib/main/atom/buildView.ts deleted file mode 100644 index c85c2fd42..000000000 --- a/lib/main/atom/buildView.ts +++ /dev/null @@ -1,66 +0,0 @@ - - -///ts:import=utils -import utils = require('../lang/utils'); ///ts:import:generated -///ts:import=project -import project = require('../lang/core/project'); ///ts:import:generated - -import os = require('os') - -import mainPanelView = require('./views/mainPanelView'); -import lineMessageView = require('./views/lineMessageView'); -import gotoHistory = require('./gotoHistory'); - -function getTitle(errorCount: number): string { - var title = ' TypeScript Build'; - if (errorCount > 0) { - title = title + ` ( - ${errorCount} - error${errorCount === 1 ? "" : "s"} - )`; - } - return title; -} - - -export function setBuildOutput(buildOutput: BuildOutput) { - - mainPanelView.panelView.clearBuild(); - - if (buildOutput.counts.errors) { - mainPanelView.panelView.setBuildPanelCount(buildOutput.counts.errors); - } - else { - mainPanelView.panelView.setBuildPanelCount(0); - } - - // Update the errors list for goto history - gotoHistory.buildOutput.members = []; - - buildOutput.outputs.forEach(output => { - if (output.success) { - return; - } - output.errors.forEach(error => { - mainPanelView.panelView.addBuild(new lineMessageView.LineMessageView({ - goToLine: (filePath, line, col) => gotoHistory.gotoLine(filePath, line, col, gotoHistory.buildOutput), - message: error.message, - line: error.startPos.line + 1, - col: error.startPos.col, - file: error.filePath, - preview: error.preview - })); - // Update the errors list for goto history - gotoHistory.buildOutput.members.push({ filePath: error.filePath, line: error.startPos.line + 1, col: error.startPos.col }); - }); - }); - - if (!buildOutput.counts.errors) { - atom.notifications.addSuccess("Build success"); - } - else if (buildOutput.counts.emitErrors) { - atom.notifications.addError("Emits errors: " + buildOutput.counts.emitErrors + " files."); - } else { - atom.notifications.addWarning('Compile failed but emit succeeded'); - } -} diff --git a/lib/main/atom/commands/build.ts b/lib/main/atom/commands/build.ts new file mode 100644 index 000000000..7137990ed --- /dev/null +++ b/lib/main/atom/commands/build.ts @@ -0,0 +1,53 @@ +import {commands} from "./registry" +import {commandForTypeScript, getFilePathPosition} from "../utils" + +commands.set("typescript:build", deps => { + return async e => { + if (!commandForTypeScript(e)) { + return + } + + const {file} = getFilePathPosition() + const client = await deps.getClient(file) + + const projectInfo = await client.executeProjectInfo({ + file, + needFileNameList: true + }) + + const files = new Set(projectInfo.body!.fileNames) + const max = files.size + const promises = [...files.values()].map(file => + _finally(client.executeCompileOnSaveEmitFile({file, forced: true}), () => { + files.delete(file) + updateStatus() + }) + ) + + Promise.all(promises).then(results => { + if (results.some(result => result.body === false)) { + throw new Error("Emit failed") + } + + deps.statusPanel.setBuildStatus({success: true}) + }).catch(() => { + deps.statusPanel.setBuildStatus({success: false}) + }) + + deps.statusPanel.setBuildStatus(undefined) + deps.statusPanel.setProgress({max, value: 0}) + + function updateStatus() { + if (files.size === 0) { + deps.statusPanel.setProgress(undefined) + } else { + deps.statusPanel.setProgress({max, value: max - files.size}) + } + } + } +}) + +function _finally(promise: Promise, callback: (result: T) => any): Promise { + promise.then(callback, callback) + return promise +} diff --git a/lib/main/atom/commands/checkAllFiles.ts b/lib/main/atom/commands/checkAllFiles.ts new file mode 100644 index 000000000..0f906fc8b --- /dev/null +++ b/lib/main/atom/commands/checkAllFiles.ts @@ -0,0 +1,52 @@ +import {commands} from "./registry" +import {commandForTypeScript, getFilePathPosition} from "../utils" + +commands.set("typescript:check-all-files", deps => { + return async e => { + if (!commandForTypeScript(e)) { + return + } + + const {file} = getFilePathPosition() + const client = await deps.getClient(file) + + const projectInfo = await client.executeProjectInfo({ + file, + needFileNameList: true + }) + + const files = new Set(projectInfo.body!.fileNames) + const max = files.size + + // There's no real way to know when all of the errors have been received and not every file from + // the files set is going to receive a a diagnostic event (typically some d.ts files). To counter + // that, we cancel the listener and close the progress bar after no diagnostics have been received + // for some amount of time. + let cancelTimeout: any + + const unregister = client.on("syntaxDiag", evt => { + clearTimeout(cancelTimeout) + cancelTimeout = setTimeout(cancel, 500) + + files.delete(evt.file) + updateStatus() + }) + + deps.statusPanel.setProgress({max, value: 0}) + client.executeGetErrForProject({file, delay: 0}) + + function cancel() { + files.clear() + updateStatus() + } + + function updateStatus() { + if (files.size === 0) { + unregister() + deps.statusPanel.setProgress(undefined) + } else { + deps.statusPanel.setProgress({max, value: max - files.size}) + } + } + } +}) diff --git a/lib/main/atom/commands/clearErrors.ts b/lib/main/atom/commands/clearErrors.ts new file mode 100644 index 000000000..26eb5b74d --- /dev/null +++ b/lib/main/atom/commands/clearErrors.ts @@ -0,0 +1,7 @@ +import {commands} from "./registry" + +commands.set("typescript:clear-errors", deps => { + return e => { + deps.clearErrors() + } +}) diff --git a/lib/main/atom/commands/commands.ts b/lib/main/atom/commands/commands.ts deleted file mode 100644 index 1509d52f6..000000000 --- a/lib/main/atom/commands/commands.ts +++ /dev/null @@ -1,603 +0,0 @@ -import parent = require("../../../worker/parent"); -import buildView = require("../buildView"); -import atomUtils = require("../atomUtils"); -import autoCompleteProvider = require("../autoCompleteProvider"); -import path = require('path'); -import documentationView = require("../views/documentationView"); -import renameView = require("../views/renameView"); -import contextView = require("../views/contextView"); -import fileSymbolsView = require("../views/fileSymbolsView"); -import projectSymbolsView = require("../views/projectSymbolsView"); -import {create as createTypeOverlay} from "../views/typeOverlayView"; -import gotoHistory = require("../gotoHistory"); -import utils = require("../../lang/utils"); -import {panelView} from "../views/mainPanelView"; -import * as url from "url"; -import {AstView, astURI, astURIFull} from "../views/astView"; -import {DependencyView, dependencyURI} from "../views/dependencyView"; -import {simpleSelectionView} from "../views/simpleSelectionView"; -import overlaySelectionView from "../views/simpleOverlaySelectionView"; -import * as outputFileCommands from "./outputFileCommands"; -import {registerRenameHandling} from "./moveFilesHandling"; -import {RefactoringsByFilePath} from "../../lang/fixmyts/quickFix"; -import escapeHtml = require('escape-html'); -import * as rView from "../views/rView"; -import {$} from "atom-space-pen-views"; -import {registerReactCommands} from "./reactCommands"; -import {getFileStatus} from "../fileStatusCache"; -import {registerJson2dtsCommands} from "./json2dtsCommands"; -import * as semanticView from "../views/semanticView"; - -// Load all the web components -export * from "../components/componentRegistry"; - -// Stack of previous cursor positions -const prevCursorPositions:{ filePath:string, cursor:TextBuffer.IPoint }[] = []; - -export function registerCommands() { - - // Stuff I've split out as we have a *lot* of commands - outputFileCommands.register(); - registerRenameHandling(); - registerReactCommands(); - registerJson2dtsCommands(); - - function applyRefactorings(refactorings: RefactoringsByFilePath) { - var paths = atomUtils.getOpenTypeScritEditorsConsistentPaths(); - var openPathsMap = utils.createMap(paths); - - let refactorPaths = Object.keys(refactorings); - let openFiles = refactorPaths.filter(p=> openPathsMap[p]); - let closedFiles = refactorPaths.filter(p=> !openPathsMap[p]); - - // if file is open change in buffer - // otherwise open the file and change the buffer range - atomUtils.getEditorsForAllPaths(refactorPaths) - .then((editorMap) => { - refactorPaths.forEach((filePath) => { - var editor = editorMap[filePath]; - editor.transact(() => { - refactorings[filePath].forEach((refactoring) => { - var range = atomUtils.getRangeForTextSpan(editor, refactoring.span); - if (!refactoring.isNewTextSnippet) { - editor.setTextInBufferRange(range, refactoring.newText); - } else { - let cursor = editor.getCursors()[0]; - (cursor).selection.setBufferRange(range); - atomUtils.insertSnippet(refactoring.newText, editor, cursor); - } - }); - }) - }); - }); - } - - // Setup custom commands NOTE: these need to be added to the keymaps - atom.commands.add('atom-text-editor', 'typescript:format-code', (e) => { - if (!atomUtils.commandForTypeScript(e)) return; - - var editor = atom.workspace.getActiveTextEditor(); - var filePath = editor.getPath(); - var selection = editor.getSelectedBufferRange(); - if (selection.isEmpty()) { - parent.formatDocument({ filePath: filePath }).then((result) => { - if (!result.edits.length) return; - editor.transact(() => { - atomUtils.formatCode(editor, result.edits); - }); - }); - } else { - parent.formatDocumentRange({ filePath: filePath, start: { line: selection.start.row, col: selection.start.column }, end: { line: selection.end.row, col: selection.end.column } }).then((result) => { - if (!result.edits.length) return; - editor.transact(() => { - atomUtils.formatCode(editor, result.edits); - }); - }); - - } - }); - atom.commands.add('atom-workspace', 'typescript:build', (e) => { - if (!atomUtils.commandForTypeScript(e)) return; - - var editor = atom.workspace.getActiveTextEditor(); - var filePath = editor.getPath(); - - atom.notifications.addInfo('Building'); - - parent.build({ filePath: filePath }).then((resp) => { - buildView.setBuildOutput(resp.buildOutput); - - resp.tsFilesWithValidEmit.forEach((tsFile) => { - let status = getFileStatus(tsFile); - status.emitDiffers = false; - }); - - // Emit never fails with an emit error, so it's probably always gonna be an empty array - // It's here just in case something changes in TypeScript compiler - resp.tsFilesWithInvalidEmit.forEach((tsFile) => { - let status = getFileStatus(tsFile); - status.emitDiffers = true; - }); - - // Update the status of the file in the current editor - panelView.updateFileStatus(filePath); - }); - }); - - var handleGoToDeclaration = (e) => { - if (!atomUtils.commandForTypeScript(e)) return; - - const editor = atom.workspace.getActiveTextEditor(); - parent.getDefinitionsAtPosition(atomUtils.getFilePathPosition()).then(res=> { - var definitions = res.definitions; - if (!definitions || !definitions.length) { - atom.notifications.addInfo('AtomTS: No definition found.'); - return; - } - - // Potential future ugly hack for something (atom or TS langauge service) path handling - // definitions.forEach((def)=> def.fileName.replace('/',path.sep)); - - // support multiple implementations. Else just go to first - if (definitions.length > 1) { - simpleSelectionView({ - items: definitions, - viewForItem: (item) => { - return ` - ${item.filePath} -
    line: ${item.position.line}
    - `; - }, - filterKey: 'filePath', - confirmed: (definition) => { - prevCursorPositions.push({ - cursor: editor.getCursorBufferPosition(), - filePath: editor.buffer.file.path - }); - atom.workspace.open(definition.filePath, { - initialLine: definition.position.line, - initialColumn: definition.position.col - }); - } - }) - } - else { - var definition = definitions[0]; - - prevCursorPositions.push({ - cursor: editor.getCursorBufferPosition(), - filePath: editor.buffer.file.path - }); - atom.workspace.open(definition.filePath, { - initialLine: definition.position.line, - initialColumn: definition.position.col - }); - } - }); - }; - - var handleReturnFromDeclaration = (e) => { - const position = prevCursorPositions.pop(); - if (!position) { - atom.notifications.addInfo('AtomTS: Previous position not found.'); - return; - } - atom.workspace.open(position.filePath, { - initialLine: position.cursor.row, - initialColumn: position.cursor.column - }); - } - - atom.commands.add('atom-workspace', 'typescript:go-to-declaration', handleGoToDeclaration); - // This exists by default in the right click menu https://github.com/TypeStrong/atom-typescript/issues/96 - atom.commands.add('atom-text-editor', 'symbols-view:go-to-declaration', handleGoToDeclaration); - - atom.commands.add('atom-workspace', 'typescript:return-from-declaration', handleReturnFromDeclaration); - atom.commands.add('atom-text-editor', 'symbols-view:return-from-declaration', handleReturnFromDeclaration); - - atom.commands.add('atom-workspace', 'typescript:create-tsconfig.json-project-file', (e) => { - if (!atomUtils.commandForTypeScript(e)) return; - - var editor = atom.workspace.getActiveTextEditor(); - var filePath = editor.getPath(); - - parent.createProject({ filePath }).then((res) => { - if (res.createdFilePath) { - atom.notifications.addSuccess(`tsconfig.json file created:
    ${res.createdFilePath}`); - } - }); - }); - - var theContextView: contextView.ContextView; - atom.commands.add('atom-text-editor', 'typescript:context-actions', (e) => { - if (!theContextView) theContextView = new contextView.ContextView(); - theContextView.show(); - }); - - atom.commands.add('atom-text-editor', 'typescript:autocomplete', (e) => { - autoCompleteProvider.triggerAutocompletePlus(); - }); - - atom.commands.add('atom-workspace', 'typescript:bas-development-testing', (e) => { - // documentationView.docView.hide(); - // documentationView.docView.autoPosition(); - // documentationView.testDocumentationView(); - // parent.debugLanguageServiceHostVersion({ filePath: atom.workspace.getActiveEditor().getPath() }) - // .then((res) => { - // console.log(res.text.length); - // // console.log(JSON.stringify({txt:res.text})) - // }); - - // atom.commands.dispatch - // atom.views.getView(atom.workspace.getActiveTextEditor()), - // 'typescript:dependency-view'); - // - /*atom.commands.dispatch( - atom.views.getView(atom.workspace.getActiveTextEditor()), - 'typescript:testing-r-view');*/ - - // atom.commands.dispatch( - // atom.views.getView(atom.workspace.getActiveTextEditor()), - // 'typescript:toggle-semantic-view'); - - atom.commands.dispatch( - atom.views.getView(atom.workspace.getActiveTextEditor()), - 'typescript:dependency-view'); - - // parent.getAST({ filePath: atom.workspace.getActiveEditor().getPath() }).then((res) => { - // console.log(res.root); - // }); - }); - - atom.commands.add('atom-workspace', 'typescript:toggle-semantic-view', (e) => { - if (!atomUtils.commandForTypeScript(e)) return; - - semanticView.toggle(); - }); - - atom.commands.add('atom-text-editor', 'typescript:rename-refactor', (e) => { - // Rename file - var editor = atom.workspace.getActiveTextEditor(); - var matched = atomUtils.editorInTheseScopes([atomUtils.knownScopes.es6import, atomUtils.knownScopes.require]); - if (matched) { - let relativePath = editor.getTextInRange(editor.bufferRangeForScopeAtCursor(matched)).replace(/['"]+/g, ''); - if (!utils.pathIsRelative(relativePath)) { - atom.notifications.addInfo('AtomTS: Can only rename external modules if they are relative files!'); - return; - } - - let completePath = path.resolve(path.dirname(atomUtils.getCurrentPath()), relativePath) + '.ts'; - - // TODO: Actually rename the file - - renameView.panelView.renameThis({ - autoSelect: false, - title: 'Rename File', - text: completePath, - openFiles: [], - closedFiles: [], - onCancel: () => { }, - onValidate: (newText): string => { - if (!newText.trim()) { - return 'If you want to abort : Press esc to exit' - } - return ''; - }, - onCommit: (newText) => { - newText = newText.trim(); - - parent.getRenameFilesRefactorings({ oldPath: completePath, newPath: newText }) - .then((res) => { - applyRefactorings(res.refactorings); - }); - } - }); - atom.notifications.addInfo('AtomTS: File rename comming soon!'); - } - - // Rename variable - else { - parent.getRenameInfo(atomUtils.getFilePathPosition()).then((res) => { - if (!res.canRename) { - atom.notifications.addInfo('AtomTS: Rename not available at cursor location'); - return; - } - - var paths = atomUtils.getOpenTypeScritEditorsConsistentPaths(); - var openPathsMap = utils.createMap(paths); - - let refactorPaths = Object.keys(res.locations); - let openFiles = refactorPaths.filter(p=> openPathsMap[p]); - let closedFiles = refactorPaths.filter(p=> !openPathsMap[p]); - - renameView.panelView.renameThis({ - autoSelect: true, - title: 'Rename Variable', - text: res.displayName, - openFiles: openFiles, - closedFiles: closedFiles, - onCancel: () => { }, - onValidate: (newText): string => { - if (newText.replace(/\s/g, '') !== newText.trim()) { - return 'The new variable must not contain a space'; - } - if (!newText.trim()) { - return 'If you want to abort : Press esc to exit' - } - return ''; - }, - onCommit: (newText) => { - newText = newText.trim(); - // if file is open change in buffer - // otherwise open the file and change the buffer range - atomUtils.getEditorsForAllPaths(Object.keys(res.locations)) - .then((editorMap) => { - Object.keys(res.locations).forEach((filePath) => { - var editor = editorMap[filePath]; - editor.transact(() => { - res.locations[filePath].forEach((textSpan) => { - var range = atomUtils.getRangeForTextSpan(editor, textSpan); - editor.setTextInBufferRange(range, newText); - }); - }) - }); - }); - } - }); - }); - } - }); - - atom.commands.add('atom-workspace', 'typescript:show-type', (e) => { - var editor = atom.workspace.getActiveTextEditor(); - var editorView = atom.views.getView(editor); - var cursor = editor.getLastCursor() - var position = atomUtils.getEditorPositionForBufferPosition(editor, cursor.getBufferPosition()); - var filePath = editor.getPath(); - parent.quickInfo({ filePath, position }).then((resp) => { - if (resp.valid) { - var decoration = editor.decorateMarker(cursor.getMarker(), { - type: 'overlay', - item: createTypeOverlay(resp.name, resp.comment) - }); - - var onKeydown = (e) => { - if (e.keyCode == 27) { // esc - destroyTypeOverlay(); - } - }; - var destroyTypeOverlay = () => { - decoration.destroy(); - cursorListener.dispose(); - editorView.removeEventListener('blur', destroyTypeOverlay); - editorView.removeEventListener('keydown', onKeydown); - }; - - var cursorListener = editor.onDidChangeCursorPosition(destroyTypeOverlay); - editorView.addEventListener('blur', destroyTypeOverlay); - editorView.addEventListener('keydown', onKeydown); - } - }); - }); - - atom.commands.add('atom-workspace', 'typescript:go-to-next', (e) => { - gotoHistory.gotoNext(); - }); - atom.commands.add('atom-workspace', 'typescript:go-to-previous', (e) => { - gotoHistory.gotoPrevious(); - }); - - atom.commands.add('atom-workspace', 'typescript:find-references', (e) => { - if (!atomUtils.commandForTypeScript(e)) return; - - parent.getReferences(atomUtils.getFilePathPosition()).then(res=> { - panelView.setReferences(res.references); - - simpleSelectionView({ - items: res.references, - viewForItem: (item) => { - return `
    - ${atom.project.relativize(item.filePath) } -
    line: ${item.position.line + 1}
    - ${escapeHtml(item.preview)} -
    `; - }, - filterKey: utils.getName(() => res.references[0].filePath), - confirmed: (definition) => { - atom.workspace.open(definition.filePath, { - initialLine: definition.position.line, - initialColumn: definition.position.col - }); - } - }) - }); - }); - - // I've needed to debounce this as it gets called multiple times for some reason - // Has to do with how we override toggle-file-symbols - var theFileSymbolsView: fileSymbolsView.FileSymbolsView; - var showFileSymbols = utils.debounce((filePath: string) => { - if (!theFileSymbolsView) theFileSymbolsView = new fileSymbolsView.FileSymbolsView(); - - parent.getNavigationBarItems({ filePath }).then((res) => { - theFileSymbolsView.setNavBarItems(res.items, filePath); - theFileSymbolsView.show(); - }); - - }, 400); - - // We support symbols view as well - atom.commands.add('.platform-linux atom-text-editor, .platform-darwin atom-text-editor,.platform-win32 atom-text-editor', 'symbols-view:toggle-file-symbols', - (e) => { - var editor = atom.workspace.getActiveTextEditor(); - if (!editor) return false; - if (path.extname(editor.getPath()) !== '.ts' && path.extname(editor.getPath()) !== '.tsx') return false; - - - // Abort it for others - e.abortKeyBinding(); - var filePath = editor.getPath(); - showFileSymbols(filePath); - }); - - - - // We support project level symbols - var theProjectSymbolsView: projectSymbolsView.ProjectSymbolsView; - var showProjectSymbols = utils.debounce((filePath: string) => { - if (!theProjectSymbolsView) theProjectSymbolsView = new projectSymbolsView.ProjectSymbolsView(); - - parent.getNavigateToItems({ filePath }).then((res) => { - theProjectSymbolsView.setNavBarItems(res.items); - theProjectSymbolsView.show(); - }); - }, 400); - atom.commands.add('.platform-linux atom-text-editor, .platform-darwin atom-text-editor,.platform-win32 atom-text-editor', 'symbols-view:toggle-project-symbols', - (e) => { - var editor = atom.workspace.getActiveTextEditor(); - if (!editor) return false; - if (path.extname(editor.getPath()) !== '.ts') return false; - - - // Abort it for others - e.abortKeyBinding(); - var filePath = editor.getPath(); - showProjectSymbols(filePath); - }); - - - atomUtils.registerOpener({ - commandSelector: 'atom-text-editor', - commandName: 'typescript:ast', - uriProtocol: astURI, - getData: () => { - return { - text: atom.workspace.getActiveTextEditor().getText(), - filePath: atomUtils.getCurrentPath() - }; - }, - onOpen: (data) => { - return new AstView(data.filePath, data.text, false); - } - }); - - atomUtils.registerOpener({ - commandSelector: 'atom-text-editor', - commandName: 'typescript:ast-full', - uriProtocol: astURIFull, - getData: () => { - return { - text: atom.workspace.getActiveTextEditor().getText(), - filePath: atomUtils.getCurrentPath() - }; - }, - onOpen: (data) => { - return new AstView(data.filePath, data.text, true); - } - }); - - atomUtils.registerOpener({ - commandSelector: 'atom-workspace', - commandName: 'typescript:dependency-view', - uriProtocol: dependencyURI, - getData: () => { - return { - filePath: atomUtils.getCurrentPath() - }; - }, - onOpen: (data) => { - return new DependencyView(data.filePath); - } - }); - - atom.commands.add('atom-text-editor', 'typescript:quick-fix', (e) => { - if (!atomUtils.commandForTypeScript(e)) return; - - var editor = atomUtils.getActiveEditor(); - var query = atomUtils.getFilePathPosition(); - - parent.getQuickFixes(query).then((result) => { - if (!result.fixes.length) { - atom.notifications.addInfo('AtomTS: No QuickFixes for current cursor position'); - return; - } - - overlaySelectionView({ - items: result.fixes, - viewForItem: (item) => { - return `
    - ${item.isNewTextSnippet ? '' : ''} - ${escapeHtml(item.display) } -
    `; - }, - filterKey: 'display', - confirmed: (item) => { - // NOTE: we can special case UI's here if we want. - - parent.applyQuickFix({ key: item.key, filePath: query.filePath, position: query.position }).then((res) => { - applyRefactorings(res.refactorings); - }); - } - }, editor); - }); - }); - - atomUtils.registerOpener({ - commandSelector: 'atom-workspace', - commandName: 'typescript:testing-r-view', - uriProtocol: rView.RView.protocol, - getData: () => { return atomUtils.getFilePath() }, - onOpen: (data) => new rView.RView({ - icon: 'repo-forked', - title: 'React View', - filePath: data.filePath, - }), - }) - - atom.commands.add('atom-workspace', 'typescript:sync', (e) => { - if (!atomUtils.commandForTypeScript(e)) return; - - panelView.softReset(); - }); - - atom.commands.add('atom-text-editor', 'typescript:toggle-breakpoint', (e) => { - if (!atomUtils.commandForTypeScript(e)) return; - - parent.toggleBreakpoint(atomUtils.getFilePathPosition()).then((res) => { - applyRefactorings(res.refactorings); - }); - }); - /// Register autocomplete commands to show documentations - /*atom.packages.activatePackage('autocomplete-plus').then(() => { - var autocompletePlus = apd.require('autocomplete-plus'); - var maxIndex = 10; - var currentSuggestionIndex = 0; - autocompletePlus.autocompleteManager.suggestionList.emitter.on('did-cancel',() => { - console.log('cancel'); - documentationView.docView.hide(); - currentSuggestionIndex = 0; - }); - - autocompletePlus.autocompleteManager.suggestionList.emitter.on('did-select-next',() => { - console.log('next'); - var length = autocompletePlus.autocompleteManager.suggestionList.items.length - if (++currentSuggestionIndex >= maxIndex) { - currentSuggestionIndex = 0; - } - documentationView.docView.show(); - documentationView.docView.autoPosition(); // TODO: only first time - }); - - autocompletePlus.autocompleteManager.suggestionList.emitter.on('did-select-previous',() => { - console.log('previous'); - var length = autocompletePlus.autocompleteManager.suggestionList.items.length - if (--currentSuggestionIndex < 0) { - currentSuggestionIndex = maxIndex - 1; - }; - documentationView.docView.show(); - }); - }).catch((err) => { - console.error(err); - });*/ - -} diff --git a/lib/main/atom/commands/findReferences.ts b/lib/main/atom/commands/findReferences.ts new file mode 100644 index 000000000..fa4c42d04 --- /dev/null +++ b/lib/main/atom/commands/findReferences.ts @@ -0,0 +1,36 @@ +import {commands} from "./registry" +import {commandForTypeScript, getFilePathPosition} from "../utils" +import {simpleSelectionView} from "../views/simpleSelectionView" +import escapeHtml = require('escape-html') + +commands.set("typescript:find-references", deps => { + return async e => { + if (!commandForTypeScript(e)) { + return + } + + const location = getFilePathPosition() + const client = await deps.getClient(location.file) + const result = await client.executeReferences(location) + + simpleSelectionView({ + items: result.body!.refs, + viewForItem: item => { + return `
    + ${atom.project.relativize(item.file)} +
    line: ${item.start.line}
    + ${escapeHtml(item.lineText.trim())} +
    ` + }, + filterKey: 'filePath', + confirmed: item => open(item) + }) + + function open(item: {file: string, start: {line: number, offset: number}}) { + atom.workspace.open(item.file, { + initialLine: item.start.line - 1, + initialColumn: item.start.offset - 1 + }) + } + } +}) diff --git a/lib/main/atom/commands/formatCode.ts b/lib/main/atom/commands/formatCode.ts new file mode 100644 index 000000000..cb57d2460 --- /dev/null +++ b/lib/main/atom/commands/formatCode.ts @@ -0,0 +1,75 @@ +import {commands} from "./registry" +import { + CodeEdit, + commandForTypeScript, + formatCode, + FormatCodeSettings, + LocationRangeQuery, + rangeToLocationRange, +} from "../utils" +import {loadProjectConfig} from "../../atomts" + +commands.set("typescript:format-code", deps => { + return async e => { + if (!commandForTypeScript(e)) { + return + } + + const editor = atom.workspace.getActiveTextEditor() + const filePath = editor.getPath() + const ranges: LocationRangeQuery[] = [] + + for (const selection of editor.getSelectedBufferRanges()) { + if (!selection.isEmpty()) { + ranges.push(rangeToLocationRange(selection)) + } + } + + // Format the whole document if there are no ranges added + if (ranges.length === 0) { + const end = editor.buffer.getEndPosition() + ranges.push({ + line: 1, + offset: 1, + endLine: end.row + 1, + endOffset: end.column + 1 + }) + } + + const client = await deps.getClient(filePath) + const options = await getProjectCodeSettings(filePath) + + // Newer versions of tsserver ignore the options argument so we need to call + // configure with the format code options to make the format command do anything. + client.executeConfigure({ + formatOptions: options + }) + + const edits: CodeEdit[] = [] + + // Collect all edits together so we can update everything in a single transaction + for (const range of ranges) { + const result = await client.executeFormat({...range, options, file: filePath}) + if (result.body) { + edits.push(...result.body) + } + } + + if (edits.length > 0) { + editor.transact(() => { + formatCode(editor, edits) + }) + } + } +}) + +async function getProjectCodeSettings(filePath: string): Promise { + const config = await loadProjectConfig(filePath) + const options = config.formatCodeOptions + + return { + indentSize: atom.config.get("editor.tabLength"), + tabSize: atom.config.get("editor.tabLength"), + ...options, + } +} diff --git a/lib/main/atom/commands/goToDeclaration.ts b/lib/main/atom/commands/goToDeclaration.ts new file mode 100644 index 000000000..18892466f --- /dev/null +++ b/lib/main/atom/commands/goToDeclaration.ts @@ -0,0 +1,58 @@ +import {commands} from "./registry" +import {commandForTypeScript, getFilePathPosition, FileLocationQuery} from "../utils" +import {simpleSelectionView} from "../views/simpleSelectionView" + +const prevCursorPositions:FileLocationQuery[] = []; + +function open(item: {file: string, start: {line: number, offset: number}}) { + atom.workspace.open(item.file, { + initialLine: item.start.line - 1, + initialColumn: item.start.offset - 1 + }) +} + +commands.set("typescript:go-to-declaration", deps => { + return async e => { + if (!commandForTypeScript(e)) { + return + } + + const location = getFilePathPosition() + const client = await deps.getClient(location.file) + const result = await client.executeDefinition(location) + + if (result.body!.length > 1) { + simpleSelectionView({ + items: result.body!, + viewForItem: item => { + return ` + ${item.file} +
    line: ${item.start.line}
    + ` + }, + filterKey: 'filePath', + confirmed: item => { + prevCursorPositions.push(location); + open(item) + } + }) + } else { + prevCursorPositions.push(location); + open(result.body![0]) + } + } +}); + +commands.set("typescript:return-from-declaration", deps => { + return async e => { + const position = prevCursorPositions.pop(); + if (!position) { + atom.notifications.addInfo('AtomTS: Previous position not found.'); + return; + } + open({ + file: position.file, + start: { line: position.line, offset: position.offset } + }); + } +}); diff --git a/lib/main/atom/commands/index.ts b/lib/main/atom/commands/index.ts new file mode 100644 index 000000000..aa241444f --- /dev/null +++ b/lib/main/atom/commands/index.ts @@ -0,0 +1,17 @@ +import {commands, Dependencies} from "./registry" + +// Import all of the command files for their side effects +import "./build" +import "./checkAllFiles" +import "./clearErrors" +import "./formatCode" +import "./findReferences" +import "./goToDeclaration" +import "./renameRefactor" + +export function registerCommands(deps: Dependencies) { + + for (const [name, command] of commands) { + atom.commands.add("atom-workspace", name, command(deps)) + } +} diff --git a/lib/main/atom/commands/json2dtsCommands.ts b/lib/main/atom/commands/json2dtsCommands.ts deleted file mode 100644 index e07612c15..000000000 --- a/lib/main/atom/commands/json2dtsCommands.ts +++ /dev/null @@ -1,19 +0,0 @@ -import * as atomUtils from "../atomUtils"; -import * as parent from "../../../worker/parent"; -import * as path from "path"; -import {convert} from "../../json2dts/json2dts"; - -/** - * register commands - */ -export function registerJson2dtsCommands() { - atom.commands.add('atom-workspace', 'typescript:JSON-to-Definition', (e) => { - if (!atomUtils.commandForTypeScript(e)) return; - var editor = atom.workspace.getActiveTextEditor(); - var filePath = editor.getPath(); - var selection = editor.getSelectedBufferRange(); - var text = editor.getSelectedText(); - var range = editor.getSelectedBufferRange(); - editor.setTextInBufferRange(range, convert(text)); - }); -} diff --git a/lib/main/atom/commands/moveFilesHandling.ts b/lib/main/atom/commands/moveFilesHandling.ts deleted file mode 100644 index cb880ba0b..000000000 --- a/lib/main/atom/commands/moveFilesHandling.ts +++ /dev/null @@ -1,12 +0,0 @@ -/** - * For rename (move) files / folders - * Waiting on https://github.com/atom/tree-view/issues/433 - */ - -export function registerRenameHandling() { - /** https://atom.io/docs/api/v0.190.0/Project#instance-onDidChangePaths */ - // var renameListener = atom.project.onDidChangePaths(function(projectPaths) { - // console.log(arguments); - // console.log(projectPaths); - // }); -} diff --git a/lib/main/atom/commands/outputFileCommands.ts b/lib/main/atom/commands/outputFileCommands.ts deleted file mode 100644 index 4bcd31111..000000000 --- a/lib/main/atom/commands/outputFileCommands.ts +++ /dev/null @@ -1,64 +0,0 @@ -import * as atomUtils from "../atomUtils"; -import * as parent from "../../../worker/parent"; -import {spawn, exec} from "child_process"; -import * as path from "path"; - -/** - * Command related to output files - */ -export function register() { - atom.commands.add('atom-workspace', 'typescript:output-toggle', (e) => { - if (!atomUtils.commandForTypeScript(e)) return; - - var query = atomUtils.getFilePath(); - var previousActivePane = atom.workspace.getActivePane() - parent.getOutputJs(query).then(res=> { - if (!res.jsFilePath) { - atom.notifications.addInfo('AtomTS: No emit for this file'); - return; - } - else { - // pane for uri needs file system path so: - var uri = res.jsFilePath.split("/").join(path.sep); - let previewPane = atom.workspace.paneForURI(uri); - if (previewPane) { - previewPane.destroyItem(previewPane.itemForURI(uri)) - } - else { - atom.workspace.open(res.jsFilePath, { split: "right" }).then(() => { - previousActivePane.activate(); - }); - } - } - }); - }); - - atom.commands.add('atom-workspace', 'typescript:output-file-execute-in-node', (e) => { - if (!atomUtils.commandForTypeScript(e)) return; - - var query = atomUtils.getFilePath(); - parent.getOutputJs(query).then(res=> { - if (!res.jsFilePath) { - atom.notifications.addInfo('AtomTS: No emit for this file'); - return; - } - else { - // spawn('cmd', ['/C', 'start ' + "node " + res.output.outputFiles[0].name]); - var command = `node ${path.basename(res.jsFilePath) }`; - console.log(command); - - exec(command, { - cwd: path.dirname(res.jsFilePath), - env: { - ELECTRON_RUN_AS_NODE: 1, - }, - }, (err, stdout, stderr) => { - console.log(stdout); - if (stderr.toString().trim().length) { - console.error(stderr); - } - }); - } - }); - }); -} diff --git a/lib/main/atom/commands/reactCommands.ts b/lib/main/atom/commands/reactCommands.ts deleted file mode 100644 index 053cb9b96..000000000 --- a/lib/main/atom/commands/reactCommands.ts +++ /dev/null @@ -1,21 +0,0 @@ -import * as atomUtils from "../atomUtils"; -import * as parent from "../../../worker/parent"; -import * as path from "path"; -import {convert} from "../../react/htmltotsx"; - -/** - * register commands - */ -export function registerReactCommands() { - atom.commands.add('atom-workspace', 'typescript:HTML-to-TSX', (e) => { - if (!atomUtils.commandForTypeScript(e)) return; - - var editor = atom.workspace.getActiveTextEditor(); - var filePath = editor.getPath(); - var selection = editor.getSelectedBufferRange(); - - var text = editor.getSelectedText(); - var range = editor.getSelectedBufferRange(); - editor.setTextInBufferRange(range, convert(text, 4)); - }); -} \ No newline at end of file diff --git a/lib/main/atom/commands/registry.ts b/lib/main/atom/commands/registry.ts new file mode 100644 index 000000000..c5d3f7b50 --- /dev/null +++ b/lib/main/atom/commands/registry.ts @@ -0,0 +1,21 @@ +import {TypescriptServiceClient} from "../../../client/client" +import {RenameView} from "../views/renameView" +import {StatusPanel} from "../../atom/components/statusPanel" +import {TypescriptBuffer} from "../../typescriptBuffer" + +export interface Dependencies { + clearErrors(): void + getTypescriptBuffer(filePath: string): Promise<{buffer: TypescriptBuffer, isOpen: boolean}> + getClient(filePath: string): Promise + renameView: RenameView + statusPanel: StatusPanel +} + +export interface CommandConstructor { + (deps: Dependencies): (e: AtomCore.CommandEvent) => any +} + +// To allow using dependency injection, but avoid having to type a lot of boilerplate, we have the +// individual command files register themselves in the below map. When the package is initializing, +// the constructors are passed the deps and return the actual commands handlers. +export const commands: Map = new Map() diff --git a/lib/main/atom/commands/renameRefactor.ts b/lib/main/atom/commands/renameRefactor.ts new file mode 100644 index 000000000..fb6717454 --- /dev/null +++ b/lib/main/atom/commands/renameRefactor.ts @@ -0,0 +1,52 @@ +import {commands} from "./registry" +import {commandForTypeScript, getFilePathPosition} from "../utils" +import {spanToRange} from "../utils" + +commands.set("typescript:rename-refactor", deps => { + return async e => { + if (!commandForTypeScript(e)) { + return + } + + const location = getFilePathPosition() + const client = await deps.getClient(location.file) + const response = await client.executeRename(location) + const {info, locs} = response.body! + + if (!info.canRename) { + return atom.notifications.addInfo("AtomTS: Rename not available at cursor location") + } + + const newName = await deps.renameView.showRenameDialog({ + autoSelect: true, + title: "Rename Variable", + text: info.displayName, + onValidate: (newText): string => { + if (newText.replace(/\s/g, "") !== newText.trim()) { + return "The new variable must not contain a space" + } + if (!newText.trim()) { + return "If you want to abort : Press esc to exit" + } + return "" + } + }) + + locs.map(async loc => { + const {buffer, isOpen} = await deps.getTypescriptBuffer(loc.file) + + buffer.buffer.transact(() => { + for (const span of loc.locs) { + buffer.buffer.setTextInRange(spanToRange(span), newName) + } + }) + + if (!isOpen) { + buffer.buffer.save() + buffer.on("saved", () => { + buffer.buffer.destroy() + }) + } + }) + } +}) diff --git a/lib/main/atom/components/componentRegistry.ts b/lib/main/atom/components/componentRegistry.ts deleted file mode 100644 index b8e25edef..000000000 --- a/lib/main/atom/components/componentRegistry.ts +++ /dev/null @@ -1 +0,0 @@ -export * from "./ts-view"; \ No newline at end of file diff --git a/lib/main/atom/components/index.ts b/lib/main/atom/components/index.ts new file mode 100644 index 000000000..d51358481 --- /dev/null +++ b/lib/main/atom/components/index.ts @@ -0,0 +1 @@ +export * from "./tsView"; diff --git a/lib/main/atom/components/statusPanel.tsx b/lib/main/atom/components/statusPanel.tsx new file mode 100644 index 000000000..fd4824cf3 --- /dev/null +++ b/lib/main/atom/components/statusPanel.tsx @@ -0,0 +1,164 @@ +import * as dom from "jsx-render-dom" +import {dirname} from "path" +import { + getFilePathRelativeToAtomProject, + openFile, +} from "../utils" + +export class StatusPanel extends HTMLElement { + + private pendingContainer: HTMLElement + private pendingCounter: HTMLElement + private pendingSpinner: HTMLElement + private configPathContainer: HTMLElement + private progress: HTMLProgressElement + private statusContainer: HTMLElement + private statusText: HTMLElement + private version: HTMLElement + + private configPath?: string + private pendingRequests: string[] + private pendingTimeout: any + + createdCallback() { + const nodes = [ +
    this.version = el } className="inline-block" />, + this.pendingContainer = el } + className="inline-block" + href="" + onClick={ evt => { + evt.preventDefault() + this.showPendingRequests() + }}> + this.pendingCounter = span }> + this.pendingSpinner = span } + className="loading loading-spinner-tiny inline-block" + style={{marginLeft: "5px", opacity: 0.5, verticalAlign: "sub"}}> + + , + this.configPathContainer = el } + className="inline-block" + href="" + onClick={ evt => { + evt.preventDefault() + this.openConfigPath() + }}/>, +
    this.statusContainer = el } + className="inline-block"> + this.statusText = el } /> +
    , + this.progress = el } + style={{ verticalAlign: "baseline" }} + className='inline-block' /> + ] + + for (const node of nodes) { + this.appendChild(node) + } + + this.setVersion(undefined) + this.setPending([], true) + this.setTsConfigPath(undefined) + this.setBuildStatus(undefined) + this.setProgress(undefined) + } + + dispose() { + this.remove() + } + + openConfigPath() { + if (this.configPath && !this.configPath.startsWith("/dev/null")) { + openFile(this.configPath) + } else { + atom.notifications.addInfo("No tsconfig for current file") + } + } + + setBuildStatus(status?: {success: boolean}) { + const container = this.statusText + if (status) { + if (status.success) { + container.classList.remove("highlight-error") + container.classList.add("highlight-success") + container.textContent = "Emit Success" + } else { + container.classList.add("highlight-error") + container.classList.remove("highlight-success") + container.textContent = "Emit Failed" + } + this.statusContainer.classList.remove("hide") + } else { + this.statusContainer.classList.add("hide") + } + } + + setProgress(progress?: {max: number, value: number}) { + if (progress) { + this.progress.max = progress.max + this.progress.value = progress.value + this.progress.classList.remove("hide") + } else { + this.progress.classList.add("hide") + } + } + + setTsConfigPath(configPath?: string) { + this.configPath = configPath + + if (configPath) { + this.configPathContainer.textContent = configPath.startsWith("/dev/null") ? "No project" : + dirname(getFilePathRelativeToAtomProject(configPath)) + + this.configPathContainer.classList.remove("hide") + } else { + this.configPathContainer.classList.add("hide") + } + } + + setVersion(version?: string) { + if (version) { + this.version.textContent = version + this.version.classList.remove("hide") + } else { + this.version.classList.add("hide") + } + } + + private _setPending(pending: string[]) { + this.pendingRequests = pending + + if (pending.length) { + this.pendingContainer.classList.remove("hide") + this.pendingCounter.textContent = pending.length.toString() + } else { + this.pendingContainer.classList.add("hide") + } + } + + setPending(pending: string[], immediate = false) { + const timeout = immediate ? 0 : 100 + clearTimeout(this.pendingTimeout) + this.pendingTimeout = setTimeout(() => this._setPending(pending), timeout) + } + + showPendingRequests() { + if (this.pendingRequests) { + atom.notifications.addInfo("Pending Requests:
    - " + this.pendingRequests.join("
    - ")) + } + } + + show() { + this.classList.remove("hide") + } + + hide() { + this.classList.add("hide") + } + + static create() { + return document.createElement("ts-status-panel") as StatusPanel + } +} + +(document as any).registerElement('ts-status-panel', StatusPanel) diff --git a/lib/main/atom/components/ts-view.ts b/lib/main/atom/components/tsView.ts similarity index 95% rename from lib/main/atom/components/ts-view.ts rename to lib/main/atom/components/tsView.ts index 5043406a2..2cfffc5e3 100644 --- a/lib/main/atom/components/ts-view.ts +++ b/lib/main/atom/components/tsView.ts @@ -2,8 +2,8 @@ // http://www.html5rocks.com/en/tutorials/webcomponents/customelements/ (look at lifecycle callback methods) export class TsView extends HTMLElement { - editorElement; - editor; + editorElement: HTMLElement + editor: AtomCore.IEditor createdCallback() { var preview = this.innerText; this.innerText = ""; diff --git a/lib/main/atom/debugAtomTs.ts b/lib/main/atom/debugAtomTs.ts deleted file mode 100644 index 1882c4534..000000000 --- a/lib/main/atom/debugAtomTs.ts +++ /dev/null @@ -1,18 +0,0 @@ - - -///ts:import=atomConfig -import atomConfig = require('./atomConfig'); ///ts:import:generated -///ts:import=typescriptGrammar -import typescriptGrammar = require('./typescriptGrammar'); ///ts:import:generated - -import TokenClass = ts.TokenClass; - -interface AtomTokenizeLineResult { - tokens: any[]; - ruleStack: any[]; -} - -export function runDebugCode(details: { filePath: string; editor: AtomCore.IEditor }) { - if (!atomConfig.debugAtomTs) return; - -} diff --git a/lib/main/atom/editorSetup.ts b/lib/main/atom/editorSetup.ts deleted file mode 100644 index 87caffb45..000000000 --- a/lib/main/atom/editorSetup.ts +++ /dev/null @@ -1,63 +0,0 @@ -/** - * Setup all the stuff we need from an editor instance and clear on editor close - */ -import {debounce} from "../lang/utils"; -import * as parent from "../../worker/parent"; -import * as atomUtils from "./atomUtils"; -import {isTransformerFile} from "../lang/transformers/transformer"; - -export function setupEditor(editor: AtomCore.IEditor) { - // - // // Quick fix decoration stuff - // var quickFixDecoration: AtomCore.Decoration = null; - // var quickFixMarker: any = null; - // function clearExistingQuickfixDecoration() { - // if (quickFixDecoration) { - // quickFixDecoration.destroy(); - // quickFixDecoration = null; - // } - // if (quickFixMarker) { - // quickFixMarker.destroy(); - // quickFixMarker = null; - // } - // } - // var queryForQuickFix = debounce((filePathPosition:{filePath:string;position:number}) => { - // parent.getQuickFixes(filePathPosition).then(res=> { - // clearExistingQuickfixDecoration(); - // if (res.fixes.length) { - // quickFixMarker = editor.markBufferRange(editor.getSelectedBufferRange()); - // quickFixDecoration = editor.decorateMarker(quickFixMarker, - // { type: "line-number", class: "quickfix" }); - // } - // }) - // }, 500); - // var cursorObserver = editor.onDidChangeCursorPosition(() => { - // try { - // // This line seems to throw an exception sometimes. - // // https://github.com/TypeStrong/atom-typescript/issues/325 - // // https://github.com/TypeStrong/atom-typescript/issues/310 - // let pathPos = atomUtils.getFilePathPosition(); - // - // // TODO: implement quickfix logic for transformed files - // if (isTransformerFile(pathPos.filePath)) { - // clearExistingQuickfixDecoration(); - // return; - // } - // - // queryForQuickFix(pathPos); - // } - // catch (ex) { - // clearExistingQuickfixDecoration(); - // } - // }); - // - // - // /** - // * On final dispose - // */ - // var destroyObserver = editor.onDidDestroy(() => { - // // Clear editor observers - // cursorObserver.dispose(); - // destroyObserver.dispose(); - // }); -} diff --git a/lib/main/atom/fileStatusCache.ts b/lib/main/atom/fileStatusCache.ts deleted file mode 100644 index ca3ee7e40..000000000 --- a/lib/main/atom/fileStatusCache.ts +++ /dev/null @@ -1,22 +0,0 @@ -/** - * We keep an in memory cache of certain knowledge points regarding a few file paths - * This file maintains that - */ -import * as path from 'path'; -import {consistentPath} from '../utils/fsUtil'; - -export interface FileStatus { - /** True if the emit on the disk differs from the potential emit of the current ts file */ - emitDiffers: boolean; - /** True if the text in the editor has been modified during the current session */ - modified: boolean; -}; - -let fileStatuses: { [index: string]: FileStatus } = {}; -export function getFileStatus(filePath: string): FileStatus { - filePath = consistentPath(filePath); - if (!fileStatuses[filePath]) { - fileStatuses[filePath] = { modified: false, emitDiffers: false }; - } - return fileStatuses[filePath]; -} diff --git a/lib/main/atom/gotoHistory.ts b/lib/main/atom/gotoHistory.ts deleted file mode 100644 index 8120e71eb..000000000 --- a/lib/main/atom/gotoHistory.ts +++ /dev/null @@ -1,92 +0,0 @@ - -export var errorsInOpenFiles: TabWithGotoPositions = { members: [] }; -export var buildOutput: TabWithGotoPositions = { members: [] }; -export var referencesOutput: TabWithGotoPositions = { members: [] }; - -/** This *must* always be set */ -export var activeList: TabWithGotoPositions = errorsInOpenFiles; - -export function gotoLine(filePath: string, line: number, col: number, list: TabWithGotoPositions) { - var activeFile, - activeEditor = atom.workspace.getActiveTextEditor(); - if (activeEditor !== undefined && activeEditor !== null) { - activeFile = activeEditor.getPath(); - } - - if (filePath !== activeFile) { - atom.workspace.open(filePath, { - initialLine: line - 1, - initialColumn: col - }); - } else { - atom.workspace.getActiveTextEditor().cursors[0].setBufferPosition([line - 1, col]); - } - - list.lastPosition = { filePath, line, col }; -} - -/** - * Uses `activeList` to go to the next error or loop back - * Storing `lastPosition` with the list allows us to be lazy elsewhere and actively find the element here - */ -function findCurrentIndexInList(): number { - // Early exit if no members - if (!activeList.members.length) { - atom.notifications.addInfo('AtomTS: no go-to members in active list'); - return -1; - } - // If we don't have a lastPosition then first is the last position - if (!activeList.lastPosition) - return 0; - - var lastPosition = activeList.lastPosition; - var index = indexOf(activeList.members, (item) => item.filePath == lastPosition.filePath && item.line == lastPosition.line); - - // if the item has since been removed go to 0 - if (index == -1) { - return 0; - } - return index; -} - -/** Uses `activeList` to go to the next position or loop back */ -export function gotoNext() { - var currentIndex = findCurrentIndexInList(); - if (currentIndex == -1) return; - - var nextIndex = currentIndex + 1; - // If next is == length then loop to zero - if (nextIndex == activeList.members.length) { - nextIndex = 0; - } - - var next = activeList.members[nextIndex]; - gotoLine(next.filePath, next.line, next.col, activeList); -} - -export function gotoPrevious() { - var currentIndex = findCurrentIndexInList(); - if (currentIndex == -1) return; - - var previousIndex = currentIndex - 1; - // If next is == -1 then loop to length - if (previousIndex == -1) { - previousIndex = activeList.members.length - 1; - } - - var previous = activeList.members[previousIndex]; - gotoLine(previous.filePath, previous.line, previous.col, activeList); -} - - -/** - * Utility Return index of element in an array - */ -function indexOf(items: T[], filter: (item: T) => boolean): number { - for (var i = 0; i < items.length; i++) { - if (filter(items[i])) { - return i; - } - } - return -1; -} diff --git a/lib/main/atom/onSaveHandler.ts b/lib/main/atom/onSaveHandler.ts deleted file mode 100644 index 16e8cde77..000000000 --- a/lib/main/atom/onSaveHandler.ts +++ /dev/null @@ -1,64 +0,0 @@ -import atomUtils = require("./atomUtils"); - -///ts:import=atomConfig -import atomConfig = require('./atomConfig'); ///ts:import:generated - -///ts:import=parent -import parent = require('../../worker/parent'); ///ts:import:generated - -import {errorView, show, panelView} from "./views/mainPanelView"; - -import {getFileStatus} from "./fileStatusCache"; - -///ts:import=debugAtomTs -import debugAtomTs = require('./debugAtomTs'); ///ts:import:generated - -export function handle(event: { filePath: string; editor: AtomCore.IEditor }) { - // As a fall back to make sure we sync up in case of anything bad happening elsewhere. - var textUpdated = parent.updateText({ filePath: event.filePath, text: event.editor.getText() }); - - // Refresh errors for file - textUpdated.then(() => { - // also invalidate linter - atomUtils.triggerLinter(); - - parent.errorsForFile({ filePath: event.filePath }) - .then((resp) => errorView.setErrors(event.filePath, resp.errors)); - }) - - show(); - - // Compile on save - parent.getProjectFileDetails({ filePath: event.filePath }).then(fileDetails => { - if (fileDetails.project.compileOnSave - && !fileDetails.project.compilerOptions.outFile - && !fileDetails.project.buildOnSave) { - - textUpdated.then(() => parent.emitFile({ filePath: event.filePath })) - .then((res) => { - let status = getFileStatus(event.filePath); - status.modified = false; - - // If there was a compilation error, the file differs from the one on the disk - status.emitDiffers = res.emitError; - panelView.updateFileStatus(event.filePath); - errorView.showEmittedMessage(res); - }); - } - - if (fileDetails.project.buildOnSave) { - // Trigger a build ;) - atom.commands.dispatch( - atom.views.getView(event.editor), - 'typescript:build'); - } - - if (fileDetails.project.atom.formatOnSave) { - // Trigger a format - atom.commands.dispatch( - atom.views.getView(event.editor), - 'typescript:format-code'); - } - - }); -} diff --git a/lib/main/atom/signatureProvider.ts b/lib/main/atom/signatureProvider.ts deleted file mode 100644 index 883409da1..000000000 --- a/lib/main/atom/signatureProvider.ts +++ /dev/null @@ -1,26 +0,0 @@ - - -///ts:import=parent -import parent = require('../../worker/parent'); ///ts:import:generated - - -export function requestHandler(config: { - editor: AtomCore.IEditor; - filePath: string; - position: number; -}) { - - /* - try { - console.log(require('views/tooltip')); - } catch (ex) { - console.error(ex); - }*/ - - /* - var signatures = config.program.languageService.getSignatureHelpItems(config.filePath, config.position); - if (!signatures) return; - */ - - // console.log(signatures); -} diff --git a/lib/main/atom/tooltipManager.ts b/lib/main/atom/tooltipManager.ts index 69101174a..33bb8a666 100644 --- a/lib/main/atom/tooltipManager.ts +++ b/lib/main/atom/tooltipManager.ts @@ -1,12 +1,8 @@ // Inspiration : https://atom.io/packages/ide-haskell // and https://atom.io/packages/ide-flow - - -///ts:import=atomUtils -import atomUtils = require('./atomUtils'); ///ts:import:generated -///ts:import=parent -import parent = require('../../worker/parent'); ///ts:import:generated +import atomUtils = require('./utils'); ///ts:import:generated +import {clientResolver} from "../atomts" import path = require('path'); import fs = require('fs'); @@ -28,6 +24,9 @@ export function attach(editorView: JQuery, editor: AtomCore.IEditor) { // Only on ".ts" files var filePath = editor.getPath(); + if (!filePath) { + return; + } var filename = path.basename(filePath); var ext = path.extname(filename); if (!atomUtils.isAllowedExtension(ext)) return; @@ -37,17 +36,18 @@ export function attach(editorView: JQuery, editor: AtomCore.IEditor) { return; } + var clientPromise = clientResolver.get(filePath) var scroll = getFromShadowDom(editorView, '.scroll-view'); var subscriber = new Subscriber(); - var exprTypeTimeout = null; - var exprTypeTooltip: TooltipView = null; + var exprTypeTimeout: any | undefined; + var exprTypeTooltip: TooltipView | undefined; // to debounce mousemove event's firing for some reason on some machines var lastExprTypeBufferPt: any; - subscriber.subscribe(scroll, 'mousemove', (e) => { + subscriber.subscribe(scroll, 'mousemove', (e: MouseEvent) => { var pixelPt = pixelPositionFromMouseEvent(editorView, e) - var screenPt = editor.screenPositionForPixelPosition(pixelPt) + var screenPt = editor.element.screenPositionForPixelPosition(pixelPt) var bufferPt = editor.bufferPositionForScreenPosition(screenPt) if (lastExprTypeBufferPt && lastExprTypeBufferPt.isEqual(bufferPt) && exprTypeTooltip) return; @@ -57,21 +57,21 @@ export function attach(editorView: JQuery, editor: AtomCore.IEditor) { clearExprTypeTimeout(); exprTypeTimeout = setTimeout(() => showExpressionType(e), 100); }); - subscriber.subscribe(scroll, 'mouseout', (e) => clearExprTypeTimeout()); - subscriber.subscribe(scroll, 'keydown', (e) => clearExprTypeTimeout()); + subscriber.subscribe(scroll, 'mouseout', () => clearExprTypeTimeout()); + subscriber.subscribe(scroll, 'keydown', () => clearExprTypeTimeout()); // Setup for clearing editor.onDidDestroy(() => deactivate()); - function showExpressionType(e: MouseEvent) { + async function showExpressionType(e: MouseEvent) { // If we are already showing we should wait for that to clear if (exprTypeTooltip) return; var pixelPt = pixelPositionFromMouseEvent(editorView, e); - pixelPt.top += editor.getScrollTop(); - pixelPt.left += editor.getScrollLeft(); - var screenPt = editor.screenPositionForPixelPosition(pixelPt); + pixelPt.top += editor.element.getScrollTop(); + pixelPt.left += editor.element.getScrollLeft(); + var screenPt = editor.element.screenPositionForPixelPosition(pixelPt); var bufferPt = editor.bufferPositionForScreenPosition(screenPt); var curCharPixelPt = rawView.pixelPositionForBufferPosition([bufferPt.row, bufferPt.column]); var nextCharPixelPt = rawView.pixelPositionForBufferPosition([bufferPt.row, bufferPt.column + 1]); @@ -79,7 +79,7 @@ export function attach(editorView: JQuery, editor: AtomCore.IEditor) { if (curCharPixelPt.left >= nextCharPixelPt.left) return; // find out show position - var offset = (editor).getLineHeightInPixels() * 0.7; + var offset = editor.getLineHeightInPixels() * 0.7; var tooltipRect = { left: e.clientX, right: e.clientX, @@ -88,26 +88,27 @@ export function attach(editorView: JQuery, editor: AtomCore.IEditor) { }; exprTypeTooltip = new TooltipView(tooltipRect); - var position = atomUtils.getEditorPositionForBufferPosition(editor, bufferPt); - - // Actually make the program manager query - parent.quickInfo({ filePath, position }).then((resp) => { - if (!resp.valid) { - hideExpressionType(); - } - else { - var message = `${escape(resp.name) }`; - if (resp.comment) { - message = message + `
    ${escape(resp.comment).replace(/(?:\r\n|\r|\n)/g, '
    ') }
    `; - } - // Sorry about this "if". It's in the code I copied so I guess its there for a reason - if (exprTypeTooltip) { - exprTypeTooltip.updateText(message); - } - } - }); - } + const client = await clientPromise + const result = await client.executeQuickInfo({ + file: filePath, + line: bufferPt.row+1, + offset: bufferPt.column+1 + }).catch(err => undefined) + + if (!result) { + return + } + const {displayString, documentation} = result.body! + + var message = `${escape(displayString) }`; + if (documentation) { + message = message + `
    ${escape(documentation).replace(/(?:\r\n|\r|\n)/g, '
    ') }
    `; + } + if (exprTypeTooltip) { + exprTypeTooltip.updateText(message); + } + } function deactivate() { subscriber.unsubscribe(); @@ -124,19 +125,15 @@ export function attach(editorView: JQuery, editor: AtomCore.IEditor) { function hideExpressionType() { if (!exprTypeTooltip) return; exprTypeTooltip.$.remove(); - exprTypeTooltip = null; + exprTypeTooltip = undefined; } } -function pixelPositionFromMouseEvent(editorView, event: MouseEvent) { +function pixelPositionFromMouseEvent(editorView: JQuery, event: MouseEvent) { var clientX = event.clientX, clientY = event.clientY; var linesClientRect = getFromShadowDom(editorView, '.lines')[0].getBoundingClientRect(); var top = clientY - linesClientRect.top; var left = clientX - linesClientRect.left; return { top: top, left: left }; } - -function screenPositionFromMouseEvent(editorView, event) { - return editorView.getModel().screenPositionForPixelPosition(pixelPositionFromMouseEvent(editorView, event)); -} diff --git a/lib/main/atom/typescriptGrammar.ts b/lib/main/atom/typescriptGrammar.ts deleted file mode 100644 index b8f383eac..000000000 --- a/lib/main/atom/typescriptGrammar.ts +++ /dev/null @@ -1,307 +0,0 @@ - - -// Help: -// https://github.com/atom/first-mate/ -// https://github.com/fdecampredon/brackets-typescript/blob/master/src/main/mode.ts -// https://github.com/p-e-w/language-javascript-semantic/blob/master/lib/javascript-semantic-grammar.coffee -// TODO: update to latest : https://github.com/atom/atom/pull/6757 - -import utils = require('../lang/utils'); -import TokenClass = ts.TokenClass; - -declare class AtomTSBaseGrammar { - constructor(registry, config) -} - -interface AtomTSTokens { tokens: any /* Atom's Token */[]; ruleStack: any[] } -interface TSToken { style: string[]; str: string } -interface TSTokens { tokens: TSToken[]; ruleStack: any[] } - -// This should be -// {Grammar} = require "first-mate" -// but doing so throws "Error: Cannot find module 'first-mate'" -(global).AtomTSBaseGrammar = require(( atom).config.resourcePath + "/node_modules/first-mate/lib/grammar.js"); - -export class TypeScriptSemanticGrammar extends AtomTSBaseGrammar { - constructor(public registry) { - super(registry, - { - name: "TypeScript", - scopeName: "source.ts", - patterns: { - // include: 'source.js' // Just makes us slower :P - }, - fileTypes: ['ts','tst'] - }); - } - - /** only set to true if we have a trailingWhiteSpace for the currenlty analyzed line */ - trailingWhiteSpaceLength = 0; - tokenizeLine(line: string, ruleStack: any[], firstLine = false): AtomTSTokens { - - // BOM handling: - // NOTE THERE ARE OTHER BOMS. I just wanted a proof of concept. - // Feel free to add here if you know of ones that are giving you pain. - if (firstLine - && line.length > 1 - && (line.charCodeAt(0) == 0xFFFE || line.charCodeAt(0) == 0xFEFF)) { - this.trailingWhiteSpaceLength = 1; - } - else { - this.trailingWhiteSpaceLength = 0; - } - - - - // Note: the Atom Tokenizer supports multiple nesting of ruleStacks - // The TypeScript tokenizer has a single final state it cares about - // So we only need to pass it the final lex state - var finalLexState = firstLine ? ts.EndOfLineState.None - : ruleStack && ruleStack.length ? ruleStack[0] - : ts.EndOfLineState.None; - - // If we are in some TS tokenizing process use TS tokenizer - // Otherwise use the specific ones we match - // Otherwise fall back to TS tokenizer - if (finalLexState !== ts.EndOfLineState.None) { - return this.getAtomTokensForLine(line, finalLexState); - } - if (line.match(this.fullTripleSlashReferencePathRegEx)) { - return this.getFullTripleSlashReferencePathTokensForLine(line); - } - else if (line.match(this.fullTripleSlashAMDNameRegEx)) { - return this.getFullTripleSlashAMDModuleNameTokensForLine(line); - } - else if (line.match(this.fullTripleSlashAMDDependencyPathRegEx)) { - return this.getFullTripleSlashAMDDependencyPathTokensForLine(line); - } - else if (line.match(this.importRequireRegex)) { - return this.getImportRequireTokensForLine(line); - } - else if (line.match(this.es6importRegex)) { - return this.getEs6importTokensForLine(line); - } - else { - return this.getAtomTokensForLine(line, finalLexState); - } - } - - /////////////////// - ////////////////////////////////// THE REMAINING CODE IS SPECIFIC TO US //////////////////////////////////////// - /////////////////// - - classifier: ts.Classifier = ts.createClassifier(); - - // Useful to tokenize these differently for autocomplete ease - fullTripleSlashReferencePathRegEx = /^(\/\/\/\s*/; - // AMD module name - fullTripleSlashAMDNameRegEx = /^(\/\/\/\s*/; - // AMD dependency path - fullTripleSlashAMDDependencyPathRegEx = /^(\/\/\/\s*/; - // Note this will not match multiple imports on same line. So shame on you - importRequireRegex = /^import\s*(\w*)\s*=\s*require\((?:'|")(\S*)(?:'|")\.*\)/; - // es6 - es6importRegex = /^import.*from.*/; - // For todo support - todoRegex = new RegExp('(BUG|TODO|FIXME|CHANGED|XXX|IDEA|HACK|NOTE)'); - - getFullTripleSlashTokensForLine(line: string, matches: RegExpMatchArray, argumentType: string): AtomTSTokens { - var tsTokensWithRuleStack = this.getTsTokensForLine(line); - if (matches[3]) { - var path = matches[3]; - if (line.indexOf('"' + path + '"') != -1) { - path = '"' + path + '"'; - } - else { - path = "'" + path + "'"; - } - var startPosition = line.indexOf(path); - var endPosition = startPosition + path.length; - var atomTokens = []; - atomTokens.push(this.registry.createToken(line.substr(0, startPosition), ['source.ts', 'keyword'])); - atomTokens.push(this.registry.createToken(line.substr(startPosition, path.length), ['source.ts', argumentType])); - atomTokens.push(this.registry.createToken(line.substr(endPosition, line.length - endPosition), ['source.ts', 'keyword'])); - return { tokens: atomTokens, ruleStack: [] }; - } - else { - return this.convertTsTokensToAtomTokens(tsTokensWithRuleStack); - } - } - - getFullTripleSlashReferencePathTokensForLine(line: string): AtomTSTokens { - var tsTokensWithRuleStack = this.getTsTokensForLine(line); - var matches = line.match(this.fullTripleSlashReferencePathRegEx); - return this.getFullTripleSlashTokensForLine(line, matches, 'reference.path.string'); - } - - getFullTripleSlashAMDModuleNameTokensForLine(line: string): AtomTSTokens { - var tsTokensWithRuleStack = this.getTsTokensForLine(line); - var matches = line.match(this.fullTripleSlashAMDNameRegEx); - return this.getFullTripleSlashTokensForLine(line, matches, 'module.name.string'); - } - - getFullTripleSlashAMDDependencyPathTokensForLine(line: string): AtomTSTokens { - var tsTokensWithRuleStack = this.getTsTokensForLine(line); - var matches = line.match(this.fullTripleSlashAMDDependencyPathRegEx); - return this.getFullTripleSlashTokensForLine(line, matches, 'dependency.path.string'); - } - - getImportRequireTokensForLine(line: string): { tokens: any /* Atom's Token */[]; ruleStack: any[] } { - var tsTokensWithRuleStack = this.getTsTokensForLine(line); - - // Based on ts tokenizer we should have a single "identifier" and a single "string" - // Update these tokens to be more specific - tsTokensWithRuleStack.tokens.forEach(t=> { - if (t.style[0] == "identifier") { - t.style = ["require.identifier"]; - } - if (t.style[0] == "string") { - t.style = ["require.path.string"]; - } - }); - - return this.convertTsTokensToAtomTokens(tsTokensWithRuleStack); - } - - getEs6importTokensForLine(line: string): { tokens: any /* Atom's Token */[]; ruleStack: any[] } { - var tsTokensWithRuleStack = this.getTsTokensForLine(line); - - // Based on ts tokenizer we should have a few "identifiers" and a single "string" - // Update these tokens to be more specific - tsTokensWithRuleStack.tokens.forEach(t=> { - if (t.style[0] == "identifier") { - t.style = ["es6import.identifier"]; - } - if (t.style[0] == "string") { - t.style = ["es6import.path.string"]; - } - }); - - return this.convertTsTokensToAtomTokens(tsTokensWithRuleStack); - } - - getTsTokensForLine(line: string, finalLexState: ts.EndOfLineState = ts.EndOfLineState.None) - : TSTokens { - - var output = this.classifier.getClassificationsForLine(line, finalLexState, true); - var ruleStack = [output.finalLexState]; - - var classificationResults = output.entries; - // TypeScript classifier returns empty for "". But Atom wants to have some Token and it needs to be "whitespace" for autoindent to work - if (!classificationResults.length) return { tokens: [{ style: ['whitespace'], str: '' }], ruleStack: ruleStack }; - - // Start with trailing whitespace taken into account. - // This is needed because classification for that is already done by ATOM internally (somehow) - var totalLength = this.trailingWhiteSpaceLength; - var tokens = utils.selectMany(classificationResults.map((info) => { - var tokenStartPosition = totalLength; - var str = line.substr(tokenStartPosition, info.length); - totalLength = totalLength + info.length; - - var style = getAtomStyleForToken(info, str); - - if (style == 'comment.block') { - let toret: TSToken[] = []; - // TODO: add todo logic - // TODO|FIXME|CHANGED|XXX|IDEA|HACK|NOTE|BUG - // REF : https://github.com/atom/language-todo/blob/master/grammars/todo.cson - let match; - while (match = this.todoRegex.exec(str)) { - var start = match.index; - var length = match[1].length; - var before = str.substr(0, start); - var actual = match[1]; - - toret.push({ style: ['comment.block'], str: before }); - toret.push({ style: ['comment.block', 'storage.type.class'], str: actual }); - - // continue with rest - str = str.substr(start + length); - } - toret.push({ style: ['comment.block'], str: str }); - return toret; - } - - return [{ style: [style], str: str }]; - })); - - return { tokens, ruleStack }; - } - - getAtomTokensForLine(line: string, finalLexState: ts.EndOfLineState): AtomTSTokens { - var tsTokensWithRuleStack = this.getTsTokensForLine(line, finalLexState); - return this.convertTsTokensToAtomTokens(tsTokensWithRuleStack); - } - - convertTsTokensToAtomTokens(tsTokensWithRuleStack: TSTokens): AtomTSTokens { - var tokens = tsTokensWithRuleStack.tokens.map((info) => { - var atomToken = this.registry.createToken(info.str, ["source.ts"].concat(info.style)); - return atomToken; - }); - - return { tokens, ruleStack: tsTokensWithRuleStack.ruleStack }; - } -} - - -/// NOTE: best way I have found for these is to just look at theme "less" files -// Alternatively just inspect the token for a .js file -function getAtomStyleForToken(token: ts.ClassificationInfo, str: string): string { - switch (token.classification) { - case TokenClass.Punctuation: - switch (str) { - case '{': - return "punctuation.section.scope.begin.ts"; - case '}': - return "punctuation.section.scope.end.ts"; - case ')': - return "meta.brace.round.ts"; - case '(': - return "meta.brace.round.ts"; - case ';': - return "punctuation.terminator.statement.ts"; - default: - return "punctuation"; - } - case TokenClass.Keyword: - switch (str) { - case 'static': - case 'public': - case 'private': - case 'protected': - case 'export': - case 'get': - case 'set': - return 'support.function'; - case 'class': - case 'module': - case 'var': - return 'storage.modifier'; - case 'function': - return 'storage.type.function'; - case 'string': - case 'number': - case 'void': - case 'boolean': - return 'keyword'; - default: - return 'keyword'; - } - case TokenClass.Operator: - return 'keyword.operator.js'; - case TokenClass.Comment: - return 'comment.block'; - case TokenClass.Whitespace: - return 'whitespace'; - case TokenClass.Identifier: - return 'identifier'; - case TokenClass.NumberLiteral: - return 'constant.numeric'; - case TokenClass.StringLiteral: - return 'string'; - case TokenClass.RegExpLiteral: - return 'constant.character'; - default: - return null; // This should not happen - } -} diff --git a/lib/main/atom/atomUtils.ts b/lib/main/atom/utils/atom.ts similarity index 74% rename from lib/main/atom/atomUtils.ts rename to lib/main/atom/utils/atom.ts index 83f238e0c..89e88720f 100644 --- a/lib/main/atom/atomUtils.ts +++ b/lib/main/atom/utils/atom.ts @@ -1,22 +1,29 @@ - - -import path = require('path'); -import fs = require('fs'); -import * as fsu from "../utils/fsUtil"; -import _atom = require('atom'); -import tsconfig = require('../tsconfig/tsconfig'); -import url = require('url'); - -// Optimized version where we do not ask this of the languageServiceHost -export function getEditorPosition(editor: AtomCore.IEditor): number { - var bufferPos = editor.getCursorBufferPosition(); - return getEditorPositionForBufferPosition(editor, bufferPos); +import * as Atom from "atom" +import * as fs from "fs" +import * as path from "path" +import * as url from "url" +import { + CodeEdit, + consistentPath, + FileLocationQuery, + LocationQuery, + spanToRange +} from "./" + +// Return line/offset position in the editor using 1-indexed coordinates +export function getEditorPosition(editor: AtomCore.IEditor): LocationQuery { + const pos = editor.getCursorBufferPosition() + return { + line: pos.row + 1, + offset: pos.column + 1 + } } -// Further optimized if you already have the bufferPos -export function getEditorPositionForBufferPosition(editor: AtomCore.IEditor, bufferPos: TextBuffer.IPoint): number { - var buffer = editor.getBuffer(); - return buffer.characterIndexForPosition(bufferPos); +export function isTypescriptFile(filePath?: string): boolean { + if (!filePath) return false + + const ext = path.extname(filePath) + return ext === ".ts" || ext === ".tsx" } export function isAllowedExtension(ext: string) { @@ -27,6 +34,7 @@ export function isActiveEditorOnDiskAndTs() { var editor = atom.workspace.getActiveTextEditor(); return onDiskAndTs(editor); } + export function onDiskAndTs(editor: AtomCore.IEditor) { if (editor instanceof require('atom').TextEditor) { var filePath = editor.getPath(); @@ -63,11 +71,12 @@ export function onDiskAndTsRelated(editor: AtomCore.IEditor) { return false; } -export function getFilePathPosition(): { filePath: string; position: number } { - var editor = atom.workspace.getActiveTextEditor(); - var filePath = editor.getPath(); - var position = getEditorPosition(editor); - return { filePath, position }; +export function getFilePathPosition(): FileLocationQuery { + const editor = atom.workspace.getActiveTextEditor() + return { + file: editor.getPath(), + ...getEditorPosition(editor) + } } export function getFilePath(): { filePath: string; } { @@ -81,7 +90,7 @@ export function getEditorsForAllPaths(filePaths: string[]): Promise<{ [filePath: var activeEditors = atom.workspace.getTextEditors().filter(editor=> !!editor.getPath()); function addConsistentlyToMap(editor: AtomCore.IEditor) { - map[fsu.consistentPath(editor.getPath())] = editor; + map[consistentPath(editor.getPath())] = editor; } activeEditors.forEach(addConsistentlyToMap); @@ -90,20 +99,19 @@ export function getEditorsForAllPaths(filePaths: string[]): Promise<{ [filePath: var newPaths = filePaths.filter(p=> !map[p]); if (!newPaths.length) return Promise.resolve(map); - var promises = newPaths.map(p=> atom.workspace.open(p, {})); + var promises = newPaths.map(p=> atom.workspace.open(p, {}) as any); // Update Atom typings! - return Promise.all(promises).then(editors=> { - editors.forEach(addConsistentlyToMap); + return Promise.all(promises).then(editors => { + editors.forEach(editor => addConsistentlyToMap(editor)); return map; }); } export function getRangeForTextSpan(editor: AtomCore.IEditor, ts: { start: number; length: number }): TextBuffer.IRange { - var buffer = editor.buffer; var start = editor.buffer.positionForCharacterIndex(ts.start); var end = editor.buffer.positionForCharacterIndex(ts.start + ts.length); - var range = new _atom.Range(start, end); + var range = new Atom.Range(start, end); return range; } @@ -115,7 +123,7 @@ export function getTypeScriptEditorsWithPaths() { } export function getOpenTypeScritEditorsConsistentPaths() { - return getTypeScriptEditorsWithPaths().map(e=> fsu.consistentPath(e.getPath())); + return getTypeScriptEditorsWithPaths().map(e=> consistentPath(e.getPath())); } export function quickNotifySuccess(htmlMessage: string) { @@ -132,17 +140,11 @@ export function quickNotifyWarning(htmlMessage: string) { }, 800); } -type Location = { line: number; col: number }; -export interface CodeEdit { - start: Location; - end: Location; - newText: string; -} export function formatCode(editor: AtomCore.IEditor, edits: CodeEdit[]) { - for (var i = edits.length - 1; i >= 0; i--) { - var edit = edits[i]; - editor.setTextInBufferRange([[edit.start.line, edit.start.col], [edit.end.line, edit.end.col]], edit.newText); - } + // The code edits need to be applied in reverse order + for (let i = edits.length - 1; i >= 0; i--) { + editor.setTextInBufferRange(spanToRange(edits[i]), edits[i].newText) + } } export function kindToColor(kind: string) { @@ -162,7 +164,10 @@ export function kindToColor(kind: string) { * https://github.com/atom-community/autocomplete-plus/pull/334#issuecomment-85697409 */ export function kindToType(kind: string) { + // variable, constant, property, value, method, function, class, type, keyword, tag, snippet, import, require switch (kind) { + case 'const': + return 'constant'; case 'interface': return 'type'; case 'identifier': @@ -171,6 +176,7 @@ export function kindToType(kind: string) { return 'function'; case 'local var': return 'variable'; + case 'let': case 'var': case 'parameter': return 'variable'; @@ -184,7 +190,7 @@ export function kindToType(kind: string) { } /** Utility functions for commands */ -export function commandForTypeScript(e) { +export function commandForTypeScript(e: AtomCore.CommandEvent) { var editor = atom.workspace.getActiveTextEditor(); if (!editor) return e.abortKeyBinding() && false; var ext = path.extname(editor.getPath()); @@ -196,7 +202,7 @@ export function commandForTypeScript(e) { /** Gets the consisten path for the current editor */ export function getCurrentPath() { var editor = atom.workspace.getActiveTextEditor(); - return fsu.consistentPath(editor.getPath()); + return consistentPath(editor.getPath()); } export var knownScopes = { @@ -246,13 +252,13 @@ export function registerOpener(config: OpenerConfig) { var uri = uriForPath(config.uriProtocol, getCurrentPath()); var old_pane = atom.workspace.paneForURI(uri); if (old_pane) { - old_pane.destroyItem(old_pane.itemForUri(uri)); + old_pane.destroyItem(old_pane.itemForURI(uri)); } atom.workspace.open(uri, config.getData()); }); - atom.workspace.addOpener(function(uri, data: T) { + atom.workspace.addOpener(function(uri: string, data: T) { try { var {protocol} = url.parse(uri); } @@ -279,7 +285,7 @@ export function triggerLinter() { * converts "c:\dev\somethin\bar.ts" to "~something\bar". */ export function getFilePathRelativeToAtomProject(filePath: string) { - filePath = fsu.consistentPath(filePath); + filePath = consistentPath(filePath); // Sample: // atom.project.relativize(`D:/REPOS/atom-typescript/lib/main/atom/atomUtils.ts`) return '~' + atom.project.relativize(filePath); @@ -298,18 +304,3 @@ export function openFile(filePath: string, position: { line?: number; col?: numb } atom.workspace.open(filePath, config); } - -/************ - * Snippets * - ************/ -var _snippetsManager; -export function _setSnippetsManager(snippetsManager) { - _snippetsManager = snippetsManager; -} -export function insertSnippet(snippet: string, editor: AtomCore.IEditor, cursor: AtomCore.ICursor) { - if (_snippetsManager) { - _snippetsManager.insertSnippet(snippet, editor, cursor); - } else { - console.error('Why no snippet manager?'); - } -} diff --git a/lib/main/utils/fsUtil.ts b/lib/main/atom/utils/fs.ts similarity index 70% rename from lib/main/utils/fsUtil.ts rename to lib/main/atom/utils/fs.ts index 5550b9ef2..37a901b1f 100644 --- a/lib/main/utils/fsUtil.ts +++ b/lib/main/atom/utils/fs.ts @@ -2,13 +2,16 @@ * Wraps fs and path into a nice "consistentPath" API */ -/** we work with "/" for all paths (so does the typescript language service) */ export function consistentPath(filePath: string): string { - return filePath.split('\\').join('/'); + return filePath.split('\\').join('/'); } import * as path from "path"; +// Atom uses system dependent path separators while Typescript uses /. Unfortunately, we +// needs this to make sure things like lint errors work. +export const systemPath: (filePath: string) => string = path.sep === "\\" ? filePath => filePath.replace(/\//g, "\\") : filePath => filePath + /** * Resolves to to an absolute path. * @param from,to,to,to... @@ -17,14 +20,6 @@ export function resolve(...args: string[]) { return consistentPath(path.resolve(...args)); } - -/** - * Could be called ends with :) - */ -export function isExt(path: string, ext: string): boolean { - return path && path.indexOf(ext, path.length - ext.length) !== -1; -} - /** * Converts "C:\boo" , "C:\boo\foo.ts" => "./foo.ts"; Works on unix as well. */ @@ -38,4 +33,4 @@ export function makeRelativePath(relativeFolder: string, filePath: string) { export function removeExt(filePath: string) { return filePath.substr(0, filePath.lastIndexOf('.')); -} \ No newline at end of file +} diff --git a/lib/main/atom/utils/index.ts b/lib/main/atom/utils/index.ts new file mode 100644 index 000000000..36afe1f86 --- /dev/null +++ b/lib/main/atom/utils/index.ts @@ -0,0 +1,3 @@ +export * from "./atom" +export * from "./fs" +export * from "./ts" diff --git a/lib/main/atom/utils/ts.ts b/lib/main/atom/utils/ts.ts new file mode 100644 index 000000000..01705a10e --- /dev/null +++ b/lib/main/atom/utils/ts.ts @@ -0,0 +1,39 @@ +import {TextSpan, CodeEdit, FormatCodeSettings} from "typescript/lib/protocol" +import {Point, Range} from "atom" + +export {TextSpan, CodeEdit, FormatCodeSettings} + +export interface LocationQuery { + line: number + offset: number +} + +export interface LocationRangeQuery extends LocationQuery { + endLine: number + endOffset: number +} + +export interface FileLocationQuery extends LocationQuery { + file: string +} + +export function locationToPoint(loc: LocationQuery): TextBuffer.IPoint { + return new Point(loc.line-1, loc.offset-1) +} + +export function spanToRange(span: TextSpan): TextBuffer.IRange { + return locationsToRange(span.start, span.end) +} + +export function locationsToRange(start: LocationQuery, end: LocationQuery): TextBuffer.IRange { + return new Range(locationToPoint(start), locationToPoint(end)) +} + +export function rangeToLocationRange(range: TextBuffer.IRange): LocationRangeQuery { + return { + line: range.start.row + 1, + offset: range.start.column + 1, + endLine: range.end.row + 1, + endOffset: range.end.column + 1 + } +} diff --git a/lib/main/atom/views/astView.ts b/lib/main/atom/views/astView.ts deleted file mode 100644 index 9c850d46a..000000000 --- a/lib/main/atom/views/astView.ts +++ /dev/null @@ -1,203 +0,0 @@ -import sp = require('atom-space-pen-views'); -import mainPanelView = require('./mainPanelView'); -import atomUtils = require("../atomUtils"); -import * as parent from "../../../worker/parent"; -import * as d3 from "d3"; - -export var astURI = "ts-ast:"; -export var astURIFull = "ts-ast-full:"; - -/** - * https://github.com/atom/atom-space-pen-views - */ -export class AstView extends sp.ScrollView { - - public mainContent: JQuery; - public rawDisplay: JQuery; - static content() { - return this.div({ class: 'ast-view' }, () => { - this.div({ style: 'display: flex' }, () => { - this.div({ outlet: 'mainContent', style: 'width: 50%' }) - this.pre({ class: 'raw-display', outlet: 'rawDisplay', style: 'width: 50%' }) - }) - }); - } - - constructor(public filePath, public text: string, public full: boolean) { - super(); - this.init(); - } - init() { - if (this.full) { - var query = parent.getASTFull({ filePath: this.filePath }); - } - else { - query = parent.getAST({ filePath: this.filePath }); - } - - query.then((res) => { - renderTree(res.root, this.mainContent, (node) => { - var display = ` -${node.kind} --------------------- AST -------------------- -${node.rawJson} --------------------- TEXT ------------------- -${this.text.substring(node.pos, node.end) } - `.trim(); - this.rawDisplay.text(display); - }); - }); - } - - getURI = () => atomUtils.uriForPath(this.full ? astURIFull : astURI, this.filePath); - getTitle = () => 'TypeScript AST' - getIconName = () => 'repo-forked' -} - - -function renderTree(rootNode: NodeDisplay, _mainContent: JQuery, display: (content: NodeDisplay) => any) { - var root ={ - dom: _mainContent[0], - jq: _mainContent - }; - - var margin = { top: 30, right: 20, bottom: 30, left: 20 }; - var width = root.jq.width() - margin.left - margin.right; - var barHeight = 30; - var barWidth = width * .8; - - var i = 0, - duration = 400; - - var tree = d3.layout.tree() - .nodeSize([0, 20]); - - var diagonal = d3.svg.diagonal() - .projection(function(d) { return [d.y, d.x]; }); - - var graphRoot = d3.select(root.dom).append("svg") - .attr("width", width + margin.left + margin.right); - var graph = graphRoot.append("g") - .attr("transform", "translate(" + margin.left + "," + margin.top + ")"); - - var selected: NodeDisplay; - select(rootNode); - - function update() { - - // Compute the flattened node list. TODO use d3.layout.hierarchy. - var nodes = tree.nodes(rootNode); - - var height = Math.max(500, nodes.length * barHeight + margin.top + margin.bottom); - - d3.select("svg").transition() - .duration(duration) - .attr("height", height); - - d3.select(self.frameElement).transition() - .duration(duration) - .style("height", height + "px"); - - // Compute the "layout". - nodes.forEach(function(n, i) { - n.x = i * barHeight; - }); - - // Update the nodes… - var node = graph.selectAll("g.node") - .data(nodes, function(d) { return d.id || (d.id = ++i); }); - - var nodeEnter = node.enter().append("g") - .attr("class", "node") - .attr("transform", function(d) { return "translate(" + rootNode.depth + "," + rootNode.nodeIndex + ")"; }) - .style("opacity", 1e-6); - - // Enter any new nodes at the parent's previous position. - nodeEnter.append("rect") - .attr("y", -barHeight / 2) - .attr("height", barHeight) - .attr("width", barWidth) - .style("fill", color) - .on("click", select); - - nodeEnter.append("text") - .attr("dy", 3.5) - .attr("dx", 5.5) - .text(function(d: NodeDisplay) { - return d.kind; - }); - - // Transition nodes to their new position. - nodeEnter.transition() - .duration(duration) - .attr("transform", function(d) { return "translate(" + d.y + "," + d.x + ")"; }) - .style("opacity", 1); - - node.transition() - .duration(duration) - .attr("transform", function(d) { return "translate(" + d.y + "," + d.x + ")"; }) - .style("opacity", 1) - .select("rect") - .style("fill", color); - - // Transition exiting nodes to the parent's new position. - node.exit().transition() - .duration(duration) - .attr("transform", function(d) { return "translate(" + rootNode.nodeIndex + "," + rootNode.depth + ")"; }) - .style("opacity", 1e-6) - .remove(); - - // Update the links… - var link = graph.selectAll("path.link") - .data(tree.links(nodes), function(d) { return d.target.id; }); - - // Enter any new links at the parent's previous position. - link.enter().insert("path", "g") - .attr("class", "link") - .attr("d", function(d) { - var o = { x: rootNode.depth, y: rootNode.nodeIndex }; - return diagonal({ source: o, target: o }); - }) - .transition() - .duration(duration) - .attr("d", diagonal); - - // Transition links to their new position. - link.transition() - .duration(duration) - .attr("d", diagonal); - - // Transition exiting nodes to the parent's new position. - link.exit().transition() - .duration(duration) - .attr("d", function(d) { - var o = { x: rootNode.depth, y: rootNode.nodeIndex }; - return diagonal({ source: o, target: o }); - }) - .remove(); - } - - function resize() { - width = root.jq.width() - margin.left - margin.right; - d3.select("svg").attr("width", width); - update(); - } - - d3.select(root.dom).on("resize", resize); - resize(); - - /** display details on click */ - function select(node: NodeDisplay) { - display(node); - selected = node; - update(); - } - - function color(d: NodeDisplay) { - if (selected == d) { - return "rgb(140, 0, 0)"; - } - return d.children ? "#000000" : "rgb(29, 166, 0)"; - } - -} diff --git a/lib/main/atom/views/awesomePanelView.ts b/lib/main/atom/views/awesomePanelView.ts deleted file mode 100644 index d5c2e2811..000000000 --- a/lib/main/atom/views/awesomePanelView.ts +++ /dev/null @@ -1,29 +0,0 @@ -import view = require('./view'); -var $ = view.$; - -export class AwesomePanelView extends view.View { - - private something: JQuery; - static content() { - return this.div({ class: 'awesome' }, - () => this.div({ class: 'dude', outlet: 'something' }) - ); - } - - init() { - this.something.html('
    tada
    '); - } -} - -export var panelView: AwesomePanelView; -export var panel: AtomCore.Panel; -export function attach() { - panelView = new AwesomePanelView({}); - panel = atom.workspace.addModalPanel({ item: panelView, priority: 1000, visible: false }); - - /*setInterval(() => { - panel.isVisible() ? panel.hide() : panel.show(); - console.log('called'); - }, 1000);*/ - -} diff --git a/lib/main/atom/views/contextView.ts b/lib/main/atom/views/contextView.ts deleted file mode 100644 index 107d915aa..000000000 --- a/lib/main/atom/views/contextView.ts +++ /dev/null @@ -1,75 +0,0 @@ -import sp = require('atom-space-pen-views'); -import mainPanelView = require('./mainPanelView'); -import * as semanticView from "./semanticView"; - -interface ContextViewItem { - title: string; -} - -var titles = { - togglePanel: 'Toggle TypeScript Panel', - tabErrors: 'Tab: Errors in Open Files', - tabLastBuild: 'Tab: Last Build Output', - tabReferences: 'Tab: Find References', - fileSemantics: 'Toggle: File Semantics', -} - -var items = Object.keys(titles).map(item=> { return { title: titles[item] } }); - -/** - * https://github.com/atom/atom-space-pen-views - */ -export class ContextView extends sp.SelectListView { - - get $(): JQuery { - return this; - } - - public setItems(items: ContextViewItem[]) { super.setItems(items) } - - /** override */ - viewForItem(item: ContextViewItem) { - return `
  • ${item.title}
  • `; - } - - /** override */ - confirmed(item: ContextViewItem) { - if (item.title == titles.togglePanel) { - mainPanelView.panelView.toggle(); - } - if (item.title == titles.tabErrors) { - mainPanelView.panelView.errorPanelSelected(); - } - if (item.title == titles.tabLastBuild) { - mainPanelView.panelView.buildPanelSelected(); - } - if (item.title == titles.tabReferences) { - mainPanelView.panelView.referencesPanelSelected(); - } - if (item.title == titles.fileSemantics){ - semanticView.toggle(); - } - - this.hide(); - } - - getFilterKey() { return 'title'; } - - panel: AtomCore.Panel = null; - show() { - this.storeFocusedElement(); - if (!this.panel) this.panel = atom.workspace.addModalPanel({ item: this }); - this.panel.show() - - this.setItems(items); - this.focusFilterEditor(); - } - hide() { - this.panel.hide(); - this.restoreFocus(); - } - - cancelled() { - this.hide(); - } -} diff --git a/lib/main/atom/views/dependencyView.ts b/lib/main/atom/views/dependencyView.ts deleted file mode 100644 index 92350245b..000000000 --- a/lib/main/atom/views/dependencyView.ts +++ /dev/null @@ -1,521 +0,0 @@ -import sp = require('atom-space-pen-views'); -import mainPanelView = require('./mainPanelView'); -import atomUtils = require("../atomUtils"); -import * as parent from "../../../worker/parent"; -import * as d3 from "d3"; -import {$} from "atom-space-pen-views"; -import {relative} from "path"; -import {consistentPath} from "../../utils/fsUtil"; -import * as os from "os"; - -export var dependencyURI = "ts-dependency:"; - -/** - * https://github.com/atom/atom-space-pen-views - */ -export class DependencyView extends sp.ScrollView { - - static content() { - return this.div({ class: 'dependency-view' }, () => { - }); - } - - get $(): JQuery { - return this; - } - - constructor(public filePath) { - super(); - this.init(); - } - init() { - parent.getDependencies({ filePath: this.filePath }).then((res) => { - renderGraph(res.links, this.$, (node) => { - }); - }); - } - - getURI = () => atomUtils.uriForPath(dependencyURI, this.filePath); - getTitle = () => 'TypeScript Dependencies' - getIconName = () => 'git-compare' -} - - -interface D3LinkNode extends D3.Layout.GraphNodeForce { - name: string -} -interface D3Link { - source: D3LinkNode; - target: D3LinkNode; -} - -var prefixes = { - circle: 'circle' -} - -function renderGraph(dependencies: FileDependency[], mainContent: JQuery, display: (content: FileDependency) => any) { - - var rootElement = mainContent[0]; - var d3Root = d3.select(rootElement) - - // Setup zoom controls - rootElement.innerHTML = ` -
    -
    - - -
    -
    - - -
    -
    - -
    -
    -
    `; - - var messagesElement = mainContent.find('.general-messages'); - messagesElement.text("No Issues Found!") - var filterElement = mainContent.find('#filter'); - filterElement.keyup((event) => { - if (event.keyCode !== 13) { - return; - } - var val = filterElement.val().trim(); - if (!val) { - nodes.classed('filtered-out', false); - links.classed('filtered-out', false); - text.classed('filtered-out', false); - return; - } - else { - nodes.classed('filtered-out', true); - links.classed('filtered-out', true); - text.classed('filtered-out', true); - let filteredNodes = graph.selectAll(`circle[data-name*="${htmlName({ name: val }) }"]`); - filteredNodes.classed('filtered-out', false); - var filteredLinks = graph.selectAll(`[data-source*="${htmlName({ name: val }) }"][data-target*="${htmlName({ name: val }) }"]`); - filteredLinks.classed('filtered-out', false); - let filteredText = graph.selectAll(`text[data-name*="${htmlName({ name: val }) }"]`); - filteredText.classed('filtered-out', false); - } - }); - let copyDisplay = mainContent.find('.copy-message>button'); - - // Compute the distinct nodes from the links. - var d3NodeLookup: { [name: string]: D3LinkNode } = {}; - var d3links: D3Link[] = dependencies.map(function(link) { - var source = d3NodeLookup[link.sourcePath] || (d3NodeLookup[link.sourcePath] = { name: link.sourcePath }); - var target = d3NodeLookup[link.targetPath] || (d3NodeLookup[link.targetPath] = { name: link.targetPath }); - return { source, target }; - }); - - // Calculate all the good stuff - var d3Graph = new D3Graph(d3links); - - // If any cycles found log them: - if (d3Graph.cycles().length) { - let cycles = d3Graph.cycles(); - let message = ''; - let textContent = ''; - for (let cycle of cycles) { - message += '

    Cycle Found:

    '; - message += cycle.join('
    ') + '
    '; - textContent += '---Cycle Found---' + os.EOL; - textContent += cycle.join(os.EOL) + os.EOL; - } - messagesElement.html(message); - - copyDisplay.show().on('click', () => { - atom.clipboard.write(textContent); - atom.notifications.addInfo('Copied!'); - }); - } else { - copyDisplay.hide(); - messagesElement.hide(); - } - - // setup weights based on degrees - Object.keys(d3NodeLookup).forEach(name=> { - var node = d3NodeLookup[name]; - node.weight = d3Graph.avgDeg(node); - }) - - // Setup zoom - var zoom = d3.behavior.zoom(); - zoom.scale(0.4); - zoom.on("zoom", onZoomChanged); - - var graph = d3Root.append("svg") - .attr('width', '100%') - .attr('height', '99%') - .call(zoom) - .append('svg:g'); - var layout = d3.layout.force() - .nodes(d3.values(d3NodeLookup)) - .links(d3links) - .gravity(.05) - .linkDistance(function(link: D3Link) { return (d3Graph.difference(link)) * 200; }) - .charge(-900) - .on("tick", tick) - .start(); - - var drag = layout.drag() - .on("dragstart", dragstart); - - /** resize initially and setup for resize */ - resize(); - d3.select(window).on("resize", resize); - centerGraph(); - - var graphWidth, graphHeight; - function resize() { - graphWidth = mainContent.width(); - graphHeight = mainContent.height(); - graph.attr("width", graphWidth) - .attr("height", graphHeight); - layout.size([graphWidth, graphHeight]) - .resume(); - } - - function centerGraph() { - var centerTranslate = [ - (graphWidth / 4), - (graphHeight / 4), - ]; - zoom.translate(centerTranslate); - // Render transition - graph.transition() - .duration(500) - .attr("transform", "translate(" + zoom.translate() + ")" + " scale(" + zoom.scale() + ")"); - } - - - function onZoomChanged() { - graph.attr("transform", "translate(" + d3.event.translate + ")" + " scale(" + d3.event.scale + ")"); - } - - - // Per-type markers, as they don't inherit styles. - graph.append("defs").selectAll("marker") - .data(["regular"]) - .enter().append("marker") - .attr("id", function(d) { return d; }) - .attr("viewBox", "0 -5 10 10") - .attr("refX", 15) - .attr("refY", -1.5) - .attr("markerWidth", 6) - .attr("markerHeight", 6) - .attr("orient", "auto") - .append("path") - .attr("d", "M0,-5L10,0L0,5"); - - var links = graph.append("g").selectAll("path") - .data(layout.links()) - .enter().append("path") - .attr("class", function(d: D3Link) { return "link"; }) - .attr("data-target", function(o: D3Link) { return htmlName(o.target) }) - .attr("data-source", function(o: D3Link) { return htmlName(o.source) }) - .attr("marker-end", function(d: D3Link) { return "url(#regular)"; }); - - var nodes = graph.append("g").selectAll("circle") - .data(layout.nodes()) - .enter().append("circle") - .attr("class", function(d: D3LinkNode) { return formatClassName(prefixes.circle, d) }) // Store class name for easier later lookup - .attr("data-name", function(o: D3LinkNode) { return htmlName(o) }) // Store for easier later lookup - .attr("r", function(d: D3LinkNode) { return Math.max(d.weight, 3); }) - .classed("inonly", function(d: D3LinkNode) { return d3Graph.inOnly(d); }) - .classed("outonly", function(d: D3LinkNode) { return d3Graph.outOnly(d); }) - .classed("circular", function(d: D3LinkNode) { return d3Graph.isCircular(d); }) - .call(drag) - .on("dblclick", dblclick) // Unstick - .on("mouseover", function(d: D3LinkNode) { onNodeMouseOver(d) }) - .on("mouseout", function(d: D3LinkNode) { onNodeMouseOut(d) }) - - var text = graph.append("g").selectAll("text") - .data(layout.nodes()) - .enter().append("text") - .attr("x", 8) - .attr("y", ".31em") - .attr("data-name", function(o: D3LinkNode) { return htmlName(o) }) - .text(function(d) { return d.name; }); - - // Use elliptical arc path segments to doubly-encode directionality. - function tick() { - links.attr("d", linkArc); - nodes.attr("transform", transform); - text.attr("transform", transform); - } - - function transform(d: D3LinkNode) { - return "translate(" + d.x + "," + d.y + ")"; - } - - function onNodeMouseOver(d: D3LinkNode) { - - // Highlight circle - var elm = findElementByNode(prefixes.circle, d); - elm.classed("hovering", true); - - updateNodeTransparencies(d, true); - } - function onNodeMouseOut(d: D3LinkNode) { - // Highlight circle - var elm = findElementByNode(prefixes.circle, d); - elm.classed("hovering", false); - - updateNodeTransparencies(d, false); - } - - function findElementByNode(prefix, node) { - var selector = '.' + formatClassName(prefix, node); - return graph.select(selector); - } - - function updateNodeTransparencies(d: D3LinkNode, fade = true) { - - // clean - nodes.classed('not-hovering', false); - nodes.classed('dimmed', false); - - if (fade) { - nodes.each(function(o: D3LinkNode) { - if (!d3Graph.isConnected(d, o)) { - this.classList.add('not-hovering'); - this.classList.add('dimmed'); - } - }); - } - - // Clean - graph.selectAll('path.link').attr('data-show', '') - .classed('outgoing', false) - .attr('marker-end', fade ? '' : 'url(#regular)') - .classed('incomming', false) - .classed('dimmed', fade); - - links.each(function(o: D3Link) { - if (o.source.name === d.name) { - this.classList.remove('dimmed'); - - // Highlight target of the link - var elmNodes = graph.selectAll('.' + formatClassName(prefixes.circle, o.target)); - elmNodes.attr('fill-opacity', 1); - elmNodes.attr('stroke-opacity', 1); - elmNodes.classed('dimmed', false); - - // Highlight arrows - let outgoingLink = graph.selectAll('path.link[data-source="' + htmlName(o.source) + '"]'); - outgoingLink.attr('data-show', 'true'); - outgoingLink.attr('marker-end', 'url(#regular)'); - outgoingLink.classed('outgoing', true); - - } - else if (o.target.name === d.name) { - this.classList.remove('dimmed'); - - // Highlight arrows - let incommingLink = graph.selectAll('path.link[data-target="' + htmlName(o.target) + '"]'); - incommingLink.attr('data-show', 'true'); - incommingLink.attr('marker-end', 'url(#regular)'); - incommingLink.classed('incomming', true); - - } - }); - - text.classed("dimmed", function(o: D3LinkNode) { - if (!fade) return false; - - if (d3Graph.isConnected(d, o)) return false; - - return true; - }); - - } - - // Helpers - function formatClassName(prefix, object: D3LinkNode) { - return prefix + '-' + htmlName(object); - } - function htmlName(object: D3LinkNode) { - return object.name.replace(/(\.|\/)/gi, '-'); - } - - function dragstart(d) { - d.fixed = true; // http://bl.ocks.org/mbostock/3750558 - d3.event.sourceEvent.stopPropagation(); // http://bl.ocks.org/mbostock/6123708 - d3.select(this).classed("fixed", true); - } - - function dblclick(d) { - d3.select(this).classed("fixed", d.fixed = false); - } -} - -interface TargetBySourceName -{ [source: string]: D3LinkNode[] } - -/** Bit of a lie about degrees : 0 is changed to 1 intentionally */ -class D3Graph { - private inDegLookup = {}; - private outDegLookup = {}; - private linkedByName = {}; - private targetsBySourceName: TargetBySourceName = {}; - private circularPaths: string[][] = []; - constructor(private links: D3Link[]) { - links.forEach(l=> { - if (!this.inDegLookup[l.target.name]) this.inDegLookup[l.target.name] = 2; - else this.inDegLookup[l.target.name]++; - - if (!this.outDegLookup[l.source.name]) this.outDegLookup[l.source.name] = 2; - else this.outDegLookup[l.source.name]++; - - // Build linked lookup for quick connection checks - this.linkedByName[l.source.name + "," + l.target.name] = 1; - - // Build an adjacency list - if (!this.targetsBySourceName[l.source.name]) this.targetsBySourceName[l.source.name] = []; - this.targetsBySourceName[l.source.name].push(l.target); - }); - - // Taken from madge - this.findCircular(); - } - public inDeg(node: D3LinkNode) { - return this.inDegLookup[node.name] ? this.inDegLookup[node.name] : 1; - } - public outDeg(node: D3LinkNode) { - return this.outDegLookup[node.name] ? this.outDegLookup[node.name] : 1; - } - public avgDeg(node: D3LinkNode) { - return (this.inDeg(node) + this.outDeg(node)) / 2; - } - public isConnected(a: D3LinkNode, b: D3LinkNode) { - return this.linkedByName[a.name + "," + b.name] || this.linkedByName[b.name + "," + a.name] || a.name == b.name; - } - /** how different are the two nodes in the link */ - public difference(link: D3Link) { - // take file path into account: - return consistentPath(relative(link.source.name, link.target.name)).split('/').length; - } - public inOnly(node: D3LinkNode) { - return !this.outDegLookup[node.name] && this.inDegLookup[node.name]; - } - public outOnly(node: D3LinkNode) { - return !this.inDegLookup[node.name] && this.outDegLookup[node.name]; - } - - /** - * Get path to the circular dependency. - */ - private getPath(parent: D3LinkNode, unresolved: { [source: string]: boolean }): string[] { - var parentVisited = false; - - return Object.keys(unresolved).filter((module) => { - if (module === parent.name) { - parentVisited = true; - } - return parentVisited && unresolved[module]; - }); - } - - /** - * A circular dependency is occurring when we see a software package - * more than once, unless that software package has all its dependencies resolved. - */ - private resolver(sourceName: string, resolved: { [source: string]: boolean }, unresolved: { [source: string]: boolean }) { - unresolved[sourceName] = true; - - if (this.targetsBySourceName[sourceName]) { - this.targetsBySourceName[sourceName].forEach((dependency) => { - if (!resolved[dependency.name]) { - if (unresolved[dependency.name]) { - this.circularPaths.push(this.getPath(dependency, unresolved)); - return; - } - this.resolver(dependency.name, resolved, unresolved); - } - }); - } - - resolved[sourceName] = true; - unresolved[sourceName] = false; - } - - /** - * Finds all circular dependencies for the given modules. - */ - private findCircular() { - var resolved: any = {}, - unresolved: any = {}; - - Object.keys(this.targetsBySourceName).forEach((sourceName) => { - this.resolver(sourceName, resolved, unresolved); - }); - }; - - /** Check if the given module is part of a circular dependency */ - public isCircular(node: D3LinkNode) { - var cyclic = false; - this.circularPaths.some((path) => { - if (path.indexOf(node.name) >= 0) { - cyclic = true; - return true; - } - return false; - }); - return cyclic; - } - - public cycles(): string[][] { - return this.circularPaths; - } -} - - -/** modified version of http://stackoverflow.com/a/26616564/390330 Takes weight into account */ -function linkArc(d: D3Link) { - var targetX = d.target.x; - var targetY = d.target.y; - - var sourceX = d.source.x; - var sourceY = d.source.y; - - var theta = Math.atan((targetX - sourceX) / (targetY - sourceY)); - var phi = Math.atan((targetY - sourceY) / (targetX - sourceX)); - - var sinTheta = d.source.weight / 2 * Math.sin(theta); - var cosTheta = d.source.weight / 2 * Math.cos(theta); - var sinPhi = (d.target.weight - 6) * Math.sin(phi); - var cosPhi = (d.target.weight - 6) * Math.cos(phi); - - // Set the position of the link's end point at the source node - // such that it is on the edge closest to the target node - if (d.target.y > d.source.y) { - sourceX = sourceX + sinTheta; - sourceY = sourceY + cosTheta; - } - else { - sourceX = sourceX - sinTheta; - sourceY = sourceY - cosTheta; - } - - // Set the position of the link's end point at the target node - // such that it is on the edge closest to the source node - if (d.source.x > d.target.x) { - targetX = targetX + cosPhi; - targetY = targetY + sinPhi; - } - else { - targetX = targetX - cosPhi; - targetY = targetY - sinPhi; - } - - // Draw an arc between the two calculated points - var dx = targetX - sourceX, - dy = targetY - sourceY, - dr = Math.sqrt(dx * dx + dy * dy); - return "M" + sourceX + "," + sourceY + "A" + dr + "," + dr + " 0 0,1 " + targetX + "," + targetY; - -} diff --git a/lib/main/atom/views/documentationView.ts b/lib/main/atom/views/documentationView.ts deleted file mode 100644 index 74ccb5863..000000000 --- a/lib/main/atom/views/documentationView.ts +++ /dev/null @@ -1,78 +0,0 @@ -import view = require('./view'); -var $ = view.$; - -export class DocumentationView extends view.View { - - private header: JQuery; - private documentation: JQuery; - static content() { - return this.div({ class: 'atom-ts-documentation padded top' }, - () => this.div( // TODO: repeat for each documentation entry - () => { - this.h2({ outlet: 'header' }); - this.p({ outlet: 'documentation' }); - }) - ); - } - - - private shown = false; - show() { this.$.addClass('active'); this.shown = true; } - hide() { this.$.removeClass('active'); this.shown = false; } - toggle() { if (this.shown) { this.hide(); } else { this.show(); } } - - setContent(content: { display: string; documentation: string; filePath: string }) { - this.header.html(content.display); - content.documentation = content.documentation.replace(/(?:\r\n|\r|\n)/g, '
    '); - this.documentation.html(content.documentation); - } - - autoPosition() { - var editor = atom.workspace.getActiveTextEditor(); - var cursor = editor.getCursors()[0]; - var cursorTop = cursor.getPixelRect().top - editor.getScrollTop(); - var editorHeight = editor.getHeight(); - - if (editorHeight - cursorTop < 100) { - this.$.removeClass('bottom'); - this.$.addClass('top'); - } - else { - this.$.removeClass('top'); - this.$.addClass('bottom') - } - } -} - -export var docView: DocumentationView; - -export function attach() { - if (docView) return; - docView = new DocumentationView({}); - $(atom.views.getView(atom.workspace)).append(docView.$); - // testDocumentationView(); -} - -export function testDocumentationView() { - docView.setContent({ - display: "this is awesome", documentation: ` - some docs - over - many - many li - - lines - long - so - long - that - it - should - - start - to - scroll - `, filePath: "some filepath" - }); - docView.show(); -} diff --git a/lib/main/atom/views/fileSymbolsView.ts b/lib/main/atom/views/fileSymbolsView.ts deleted file mode 100644 index 7e8d73815..000000000 --- a/lib/main/atom/views/fileSymbolsView.ts +++ /dev/null @@ -1,64 +0,0 @@ -import sp = require('atom-space-pen-views'); -import mainPanelView = require('./mainPanelView'); -import atomUtils = require("../atomUtils"); - - -/** - * https://github.com/atom/atom-space-pen-views - */ -export class FileSymbolsView extends sp.SelectListView { - - get $(): JQuery { - return this; - } - - public filePath: string; - public setNavBarItems(tsItems: NavigationBarItem[], filePath) { - - var items: NavigationBarItem[] = tsItems; - - this.filePath = filePath; - - super.setItems(items) - } - - /** override */ - viewForItem(item: NavigationBarItem) { - return ` -
  • -
    ${ Array(item.indent * 2).join(' ') + (item.indent ? "\u221F " : '') + item.text}
    -
    ${item.kind}
    -
    line: ${item.position.line + 1}
    -
  • - `; - } - - /** override */ - confirmed(item: NavigationBarItem) { - atom.workspace.open(this.filePath, { - initialLine: item.position.line, - initialColumn: item.position.col - }); - - this.hide(); - } - - getFilterKey() { return 'text'; } - - panel: AtomCore.Panel = null; - show() { - this.storeFocusedElement(); - if (!this.panel) this.panel = atom.workspace.addModalPanel({ item: this }); - this.panel.show() - - this.focusFilterEditor(); - } - hide() { - this.panel.hide(); - this.restoreFocus(); - } - - cancelled() { - this.hide(); - } -} diff --git a/lib/main/atom/views/lineMessageView.ts b/lib/main/atom/views/lineMessageView.ts deleted file mode 100644 index de64bb9e1..000000000 --- a/lib/main/atom/views/lineMessageView.ts +++ /dev/null @@ -1,88 +0,0 @@ -import view = require('./view'); -var $ = view.$; -import path = require('path'); - -export interface ViewOptions { - /** This is needed to support good goto next / goto previous logic - * We inform the parent about our navigation - */ - goToLine: (filePath: string, line: number, col: number) => any; - /** your message to the people */ - message: string; - /** what line are we talking about? */ - line: number; - /** which column */ - col: number; - /** so, was that in some other file? */ - file: string; - /** lets you display a code snippet inside a pre tag */ - preview: string; -} - -export class LineMessageView extends view.View { - - public index: number; - private position: JQuery; - private contents: JQuery; - private code: JQuery; - static content() { - return this.div({ - class: 'line-message' - }, () => { - this.div({ - class: 'text-subtle inline-block', - outlet: 'position', - click: 'goToLine', - style: 'cursor: pointer;' - }); - this.div({ - class: 'message inline-block', - outlet: 'contents' - }); - - this.pre({ - class: 'preview', - outlet: 'code', - click: 'goToLine', - style: 'cursor: pointer;' - }); - }); - } - - init() { - var message = 'at line ' + this.options.line; - - if (this.options.file !== undefined) { - message += ', file ' + this.options.file; - } - this.position.text(message); - this.contents.text(this.options.message); - - if (this.options.preview) { - this.code.text(this.options.preview); - } else { - this.code.remove(); - } - } - - goToLine() { - this.options.goToLine(this.options.file, this.options.line, this.options.col); - } - - getSummary() { - var pos = this.options.line.toString(); - if (this.options.file !== undefined) { - pos += ', ' + this.options.file; - } - return { - summary: pos + ' ' + this.options.message, - rawSummary: true, - handler: function(element) { - $(element) - .css('cursor', 'pointer') - .click(this.goToLine.bind(this)); - }.bind(this) - }; - } - -} diff --git a/lib/main/atom/views/mainPanelView.ts b/lib/main/atom/views/mainPanelView.ts deleted file mode 100644 index eb2584ae9..000000000 --- a/lib/main/atom/views/mainPanelView.ts +++ /dev/null @@ -1,578 +0,0 @@ -import view = require('./view'); -var $ = view.$; - -import lineMessageView = require('./lineMessageView'); -import atomUtils = require("../atomUtils"); -import parent = require("../../../worker/parent"); -import * as utils from "../../lang/utils"; -import { FileStatus, getFileStatus } from "../fileStatusCache"; - -var panelHeaders = { - error: 'Errors In Open Files', - build: 'Last Build Output', - references: 'References' -} - -import gotoHistory = require('../gotoHistory'); - -export class MainPanelView extends view.View { - - private tsconfigInUse: JQuery; - private fileStatus: JQuery; - private btnFold: JQuery; - private btnSoftReset: JQuery; - private summary: JQuery; - private heading: JQuery; - - private errorPanelBtn: JQuery; - private buildPanelBtn: JQuery; - private referencesPanelBtn: JQuery; - private errorBody: JQuery; - private buildBody: JQuery; - private referencesBody: JQuery; - - private buildProgress: JQuery; - - private sectionPending: JQuery; - private txtPendingCount: JQuery; - private pendingRequests: string[] = []; - - static content() { - var btn = (view, text, className: string = '') => - this.button({ - 'class': `btn btn-sm ${className}`, - 'click': `${view}PanelSelectedClick`, - 'outlet': `${view}PanelBtn` - }, text); - - this.div({ - class: 'atomts atomts-main-panel-view native-key-bindings', - tabindex: '-1' - }, () => { - this.div({ - class: 'layout horizontal', - style: '-webkit-user-select: none; flex-wrap: wrap', - dblclick: 'toggle' - }, () => { - this.span({ - class: 'layout horizontal atomts-panel-header', - style: 'align-items: center' - }, () => { - this.span({ - style: 'cursor: pointer; color: rgb(0, 148, 255); -webkit-user-select: none; white-space: nowrap; overflow: hidden; text-overflow: ellipsis; min-width: 16px', - click: 'toggle' - }, () => { - this.span({ class: 'icon-microscope' }); - this.span({ style: 'font-weight: bold' }, 'TypeScript'); - }); - - this.div({ - class: 'btn-group', - style: 'margin-left: 6px; flex: 1 0 auto' - }, () => { - btn('error', panelHeaders.error, 'selected') - btn('build', panelHeaders.build) - btn('references', panelHeaders.references) - }); - }); - - this.span({ - class: 'layout horizontal atomts-panel-header', - style: 'align-items: center; flex: 1 1 auto; line-height: 24px;' // Line height is equal to height of github loading icon - }, () => { - this.div({ - style: 'cursor: pointer;', - click: 'clickedCurrentTsconfigFilePath' - }, () => { - this.span({ - outlet: 'tsconfigInUse' - }); - }); - - this.div({ - style: 'overflow-x: visible; white-space: nowrap;' - }, () => { - this.span({ - style: 'margin-left: 10px; transition: color 1s', // Added transition to make it easy to see *yes I just did this compile*. - outlet: 'fileStatus' - }); - }); - - this.div({ - class: 'heading-summary flex', - style: 'margin-left: 5px; overflow: hidden; white-space:nowrap; text-overflow: ellipsis', - outlet: 'summary' - }); - - this.progress({ - class: 'inline-block build-progress', - style: 'display: none; color: red', - outlet: 'buildProgress' - }); - - this.span({ - class: 'section-pending', - outlet: 'sectionPending', - click: 'showPending' - }, () => { - this.span({ - outlet: 'txtPendingCount', - style: 'cursor: pointer; margin-left: 5px', - }); - - this.span({ - class: 'loading loading-spinner-tiny inline-block', - style: 'cursor: pointer; margin-left: 5px' - }); - }); - - this.div({ - class: 'heading-buttons', - style: 'margin-left: 5px' - }, () => { - this.span({ - class: 'heading-fold icon-unfold', - style: 'cursor: pointer; margin-right: 10px', - outlet: 'btnFold', - click: 'toggle' - }); - - this.span({ - class: 'heading-fold icon-sync', - style: 'cursor: pointer', - outlet: 'btnSoftReset', - click: 'softReset' - }); - }); - }); - - this.div({ - class: 'panel-body atomts-panel-body', - outlet: 'errorBody', - style: 'overflow-y: auto; flex: 1 0 100%; display: none' - }); - this.div({ - class: 'panel-body atomts-panel-body', - outlet: 'buildBody', - style: 'overflow-y: auto; flex: 1 0 100%; display: none' - }); - this.div({ - class: 'panel-body atomts-panel-body', - outlet: 'referencesBody', - style: 'overflow-y: auto; flex: 1 0 100%; display: none' - }); - }); - }); - } - - - init() { - this.buildPanelBtn.html(`${panelHeaders.build} ( No Build )`); - this.buildBody.html(' No Build. Press ( F12 ) to start a build for an active TypeScript file\'s project. ') - - this.referencesPanelBtn.html(`${panelHeaders.references} ( No Search )`) - this.referencesBody.html(' You haven\'t searched for TypeScript references yet. ') - } - - softReset() { - var editor = atom.workspace.getActiveTextEditor(); - var prom = parent.softReset({ filePath: editor.getPath(), text: editor.getText() }) - .then(() => { - - }); - if (atomUtils.onDiskAndTs(editor)) { - prom.then(() => { - atomUtils.triggerLinter(); - - return parent.errorsForFile({ filePath: editor.getPath() }) - }) - .then((resp) => errorView.setErrors(editor.getPath(), resp.errors)); - } - } - - ///////////// Current TSconfig - private fullTsconfigPath: string; - setTsconfigInUse(tsconfigFilePath: string) { - this.fullTsconfigPath = tsconfigFilePath; - if (!this.fullTsconfigPath) { - this.tsconfigInUse.text('no tsconfig.json'); - } - else { - var path = atomUtils.getFilePathRelativeToAtomProject(tsconfigFilePath); - this.tsconfigInUse.text(`${path}`); - } - } - clickedCurrentTsconfigFilePath() { - if (!this.fullTsconfigPath) { - atom.notifications.addInfo("No tsconfig for current file") - return; - } - else{ - atomUtils.openFile(this.fullTsconfigPath); - } - } - - ///////////// Change JS File Status - updateFileStatus(filePath: string) { - parent.getProjectFileDetails({ filePath }).then(fileDetails => { - if (!fileDetails.project.compileOnSave) { - this.fileStatus.addClass("hidden"); - } else { - let status = getFileStatus(filePath); - this.fileStatus.removeClass('icon-x icon-check text-error text-success hidden'); - if (status.emitDiffers || status.modified) { - this.fileStatus.text('JS Outdated'); - this.fileStatus.addClass('icon-x text-error'); - } else { - this.fileStatus.text('JS Current'); - this.fileStatus.addClass('icon-check text-success'); - } - } - }); - } - - ///////////// Pending Requests - showPending() { - atom.notifications.addInfo('Pending Requests:
    - ' + this.pendingRequests.join('
    - ')); - } - updatePendingRequests(pending: string[]) { - this.pendingRequests = pending; - this.txtPendingCount.html(`${this.pendingRequests.length}`); - - this.sectionPending.stop(); - if (pending.length) { - this.sectionPending.animate({opacity: 0.5}, 500); - } - else { - this.sectionPending.animate({opacity: 0}, 200); - } - } - - ///// Panel selection - errorPanelSelectedClick() { - this.toggleIfThisIsntSelected(this.errorPanelBtn); - this.errorPanelSelected(); - } - errorPanelSelected() { - this.selectPanel(this.errorPanelBtn, this.errorBody, gotoHistory.errorsInOpenFiles); - } - - buildPanelSelectedClick() { - this.toggleIfThisIsntSelected(this.buildPanelBtn); - this.buildPanelSelected(); - } - buildPanelSelected() { - this.selectPanel(this.buildPanelBtn, this.buildBody, gotoHistory.buildOutput); - } - - referencesPanelSelectedClick() { - this.toggleIfThisIsntSelected(this.referencesPanelBtn); - this.referencesPanelSelected(); - } - referencesPanelSelected(forceExpand = false) { - this.selectPanel(this.referencesPanelBtn, this.referencesBody, gotoHistory.referencesOutput); - } - - private toggleIfThisIsntSelected(btn:JQuery){ - if(btn.hasClass('selected')){ - this.expanded = !this.expanded; - } - } - - private selectPanel(btn: JQuery, body: JQuery, activeList: TabWithGotoPositions) { - var buttons = [this.errorPanelBtn, this.buildPanelBtn, this.referencesPanelBtn]; - var bodies = [this.errorBody, this.buildBody, this.referencesBody]; - - buttons.forEach(b=> { - if (b !== btn) - b.removeClass('selected') - else - b.addClass('selected'); - }); - bodies.forEach(b=> { - if (!this.expanded) { - b.hide('fast') - } - else { - if (b !== body) - b.hide('fast') - else { - body.show('fast'); - } - } - }); - - gotoHistory.activeList = activeList; - gotoHistory.activeList.lastPosition = null; - } - - private setActivePanel() { - if (this.errorPanelBtn.hasClass('selected')) { - this.errorPanelSelected(); - } - if (this.buildPanelBtn.hasClass('selected')) { - this.buildPanelSelected(); - } - if (this.referencesPanelBtn.hasClass('selected')) { - this.referencesPanelSelected(); - } - } - - private expanded = false; - toggle() { - this.expanded = !this.expanded; - this.setActivePanel(); - } - - ////////////// REFERENCES - setReferences(references: ReferenceDetails[]) { - // Select it - this.referencesPanelSelected(true); - - this.referencesBody.empty(); - - if (references.length == 0) { - var title = `${panelHeaders.references} ( No References )`; - this.referencesPanelBtn.html(title); - this.referencesBody.html('No references found \u2665'); - atom.notifications.addInfo('AtomTS: No References Found.'); - return; - } - - var title = `${panelHeaders.references} ( Found: ${references.length} )`; - this.referencesPanelBtn.html(title); - - gotoHistory.referencesOutput.members = []; - for (let ref of references) { - - var view = new lineMessageView.LineMessageView({ - goToLine: (filePath, line, col) => gotoHistory.gotoLine(filePath, line, col, gotoHistory.referencesOutput), - message: '', - line: ref.position.line + 1, - col: ref.position.col, - file: ref.filePath, - preview: ref.preview - }); - - this.referencesBody.append(view.$); - - // Update the list for goto history - gotoHistory.referencesOutput.members.push({ filePath: ref.filePath, line: ref.position.line + 1, col: ref.position.col }); - } - } - - ///////////// ERROR - private clearedError = true; - clearError() { - this.clearedError = true; - this.clearSummary(); - this.errorBody.empty(); - } - - addError(view: lineMessageView.LineMessageView) { - if (this.clearedError && view.getSummary) { - // This is the first message, so use it to - // set the summary - this.setErrorSummary(view.getSummary()); - } - this.clearedError = false; - - this.errorBody.append(view.$); - } - - /*TODO: Type this*/ - setErrorSummary(summary: any) { - var message = summary.summary, - className = summary.className, - raw = summary.rawSummary || false, - handler = summary.handler || undefined; - // Set the new summary - this.summary.html(message); - - if (className) { - this.summary.addClass(className); - } - if (handler) { - handler(this.summary); - } - } - - clearSummary() { - this.summary.html(''); - this.summary.off(); - } - - setErrorPanelErrorCount(fileErrorCount: number, totalErrorCount: number) { - var title = `${panelHeaders.error} ( No Errors )`; - if (totalErrorCount > 0) { - title = `${panelHeaders.error} ( - ${fileErrorCount} - file${fileErrorCount === 1 ? "" : "s"} - ${totalErrorCount} - error${totalErrorCount === 1 ? "" : "s"} - )`; - } - else { - this.clearSummary(); - this.errorBody.html('No errors in open files \u2665'); - } - - this.errorPanelBtn.html(title); - } - - ///////////////////// BUILD - setBuildPanelCount(errorCount: number, inProgressBuild = false) { - var titleMain = inProgressBuild ? "Build Progress" : panelHeaders.build; - var title = `${titleMain} ( No Errors )`; - if (errorCount > 0) { - title = `${titleMain} ( - ${errorCount} - error${errorCount === 1 ? "" : "s"} - )`; - } - else { - if (!inProgressBuild) - this.buildBody.html('No errors in last build \u2665'); - } - this.buildPanelBtn.html(title); - } - - clearBuild() { - this.buildBody.empty(); - } - - addBuild(view: lineMessageView.LineMessageView) { - this.buildBody.append(view.$); - } - - setBuildProgress(progress: BuildUpdate) { - // just for the first time - if (progress.builtCount == 1) { - this.buildProgress.show(); - this.buildProgress.removeClass('warn'); - this.buildBody.html('Things are looking good \u2665'); - - // Update the errors list for goto history - gotoHistory.buildOutput.members = []; - } - - // For last time we don't care just return - if (progress.builtCount == progress.totalCount) { - this.buildProgress.hide(); - return; - } - - this.buildProgress.prop('value', progress.builtCount); - this.buildProgress.prop('max', progress.totalCount); - - this.setBuildPanelCount(progress.errorCount, true); - - if (progress.firstError) { - this.buildProgress.addClass('warn'); - this.clearBuild(); - } - - if (progress.errorsInFile.length) { - progress.errorsInFile.forEach(error => { - this.addBuild(new lineMessageView.LineMessageView({ - goToLine: (filePath, line, col) => gotoHistory.gotoLine(filePath, line, col, gotoHistory.buildOutput), - message: error.message, - line: error.startPos.line + 1, - col: error.startPos.col, - file: error.filePath, - preview: error.preview - })); - // Update the errors list for goto history - gotoHistory.buildOutput.members.push({ filePath: error.filePath, line: error.startPos.line + 1, col: error.startPos.col }); - }); - } - } -} - -export var panelView: MainPanelView; -var panel: AtomCore.Panel; -export function attach() { - - // Only attach once - if (panelView) return; - - panelView = new MainPanelView({}); - panel = atom.workspace.addBottomPanel({ item: panelView, priority: 1000, visible: true }); - panelView.setErrorPanelErrorCount(0, 0); -} - -export function show() { - if (!panelView) return; - panelView.$.show(); -} - -export function hide() { - if (!panelView) return; - panelView.$.hide(); -} - - -export module errorView { - const MAX_ERRORS = 50; - - var filePathErrors: utils.Dict = new utils.Dict(); - - export var setErrors = (filePath: string, errorsForFile: CodeError[]) => { - if (!panelView || !panelView.clearError) { - // if not initialized, just quit; might happen when atom is first opened. - return; - } - - if (!errorsForFile.length) { - filePathErrors.clearValue(filePath); - } else { - // Currently we are limiting errors - // Too many errors crashes our display - if (errorsForFile.length > MAX_ERRORS) { - errorsForFile = errorsForFile.slice(0, MAX_ERRORS); - } - - filePathErrors.setValue(filePath, errorsForFile) - } - - // TODO: this needs to be optimized at some point - panelView.clearError(); - - var fileErrorCount = filePathErrors.keys().length; - - // Update the errors list for goto history - gotoHistory.errorsInOpenFiles.members = []; - - if (!fileErrorCount) { - panelView.setErrorPanelErrorCount(0, 0); - } - else { - var totalErrorCount = 0; - for (var path in filePathErrors.table) { - filePathErrors.getValue(path).forEach((error: CodeError) => { - totalErrorCount++; - panelView.addError(new lineMessageView.LineMessageView({ - goToLine: (filePath, line, col) => gotoHistory.gotoLine(filePath, line, col, gotoHistory.errorsInOpenFiles), - message: error.message, - line: error.startPos.line + 1, - col: error.startPos.col, - file: error.filePath, - preview: error.preview - })); - // Update the errors list for goto history - gotoHistory.errorsInOpenFiles.members.push({ filePath: error.filePath, line: error.startPos.line + 1, col: error.startPos.col }); - }); - } - panelView.setErrorPanelErrorCount(fileErrorCount, totalErrorCount); - } - }; - - export function showEmittedMessage(output: EmitOutput) { - if (output.emitError) { - atom.notifications.addError('TS Emit Failed'); - } else if (!output.success) { - atomUtils.quickNotifyWarning('Compile failed but emit succeeded
    ' + output.outputFiles.join('
    ')); - } - } - -} diff --git a/lib/main/atom/views/plainMessageView.ts b/lib/main/atom/views/plainMessageView.ts deleted file mode 100644 index 544b7d7e8..000000000 --- a/lib/main/atom/views/plainMessageView.ts +++ /dev/null @@ -1,31 +0,0 @@ -import view = require('./view'); -var $ = view.$; -import path = require('path'); - -export interface ViewOptions { - /** your message to the people */ - message: string; - className: string; -} - -export class PlainMessageView extends view.View { - - static content() { - this.div({ - class: 'plain-message' - }); - } - - init() { - this.$.html(this.options.message); - this.$.addClass(this.options.className); - } - - getSummary() { - return { - summary: this.options.message, - rawSummary: true, - className: this.options.className - }; - } -} \ No newline at end of file diff --git a/lib/main/atom/views/projectSymbolsView.ts b/lib/main/atom/views/projectSymbolsView.ts deleted file mode 100644 index ce43e199f..000000000 --- a/lib/main/atom/views/projectSymbolsView.ts +++ /dev/null @@ -1,71 +0,0 @@ -import sp = require('atom-space-pen-views'); -import mainPanelView = require('./mainPanelView'); -import atomUtils = require("../atomUtils"); - - -/** - * https://github.com/atom/atom-space-pen-views - */ -export class ProjectSymbolsView extends sp.SelectListView { - - get $(): JQuery { - return this; - } - - get filterView(): { - $: JQuery, - model: AtomCore.IEditor - } { - return { - $: this.filterEditorView, - model: (this.filterEditorView).model - }; - } - - public setNavBarItems(tsItems: NavigateToItem[]) { - super.setMaxItems(40); - - var items: NavigateToItem[] = tsItems; - super.setItems(items) - } - - /** override */ - viewForItem(item: NavigateToItem) { - return ` -
  • -
    ${item.name}
    -
    ${item.kind}
    -
    ${item.fileName} : ${item.position.line + 1}
    -
  • - `; - } - - /** override */ - confirmed(item: NavigateToItem) { - atom.workspace.open(item.filePath, { - initialLine: item.position.line, - initialColumn: item.position.col - }); - - this.hide(); - } - - getFilterKey() { return 'name'; } - - panel: AtomCore.Panel = null; - show() { - this.storeFocusedElement(); - if (!this.panel) this.panel = atom.workspace.addModalPanel({ item: this }); - this.panel.show() - - this.focusFilterEditor(); - } - hide() { - this.panel.hide(); - this.restoreFocus(); - } - - cancelled() { - this.hide(); - } -} diff --git a/lib/main/atom/views/rView.tsx b/lib/main/atom/views/rView.tsx deleted file mode 100644 index 355d66d9f..000000000 --- a/lib/main/atom/views/rView.tsx +++ /dev/null @@ -1,74 +0,0 @@ -// Sample implementation of a react view -// DOCS: -// http://facebook.github.io/react/blog/2015/01/27/react-v0.13.0-beta-1.html#es6-classes -// https://facebook.github.io/react/docs/component-specs.html - -import {uriForPath} from "../atomUtils"; -import * as sp from "atom-space-pen-views"; - -import React = require('react'); - -interface Props { initialCount: number } -interface State { count: number } - -class MyComponent extends React.Component{ - - static defaultProps = { count: 0 }; - state = { count: 0 }; - constructor(props: Props) { - super(props); - } - - interval: number; - componentDidMount() { - this.interval = setInterval(() => { - this.setState({ count: this.state.count + 1 }); - }); - } - - stop = () => { - clearInterval(this.interval); - } - - render() { - return
    - This is a test: {this.state.count} -
    - } -} - - -/** - * A base class for creating React based views in atom - */ -export class RView extends sp.ScrollView { - - public mainContent: JQuery; - public get rootDomElement() { - return this.mainContent[0]; - } - static content() { - return this.div({ class: 'atomts atomts-r-view native-key-bindings' }, () => { - this.div({ outlet: 'mainContent layout' }); - }); - } - - constructor(public config: { - icon: string; - title: string; - filePath: string; - }) { - super(); - - React.render(React.createElement(MyComponent, {}), this.rootDomElement); - } - - - /** Override */ - static protocol: string = 'atomtsview:'; - - public get $() { return this as any as JQuery; } - private getURI = () => uriForPath((this.constructor as any).protocol, this.config.filePath); - private getTitle = () => this.config.title; - private getIconName = () => this.config.icon; -} diff --git a/lib/main/atom/views/renameView.ts b/lib/main/atom/views/renameView.ts index 37c2ca5d3..623a36343 100644 --- a/lib/main/atom/views/renameView.ts +++ b/lib/main/atom/views/renameView.ts @@ -2,7 +2,7 @@ import view = require('./view'); var $ = view.$; var html = require('../../../../views/renameView.html'); -interface EditorView extends JQuery { +interface EditorViewzz extends JQuery { model: AtomCore.IEditor; } @@ -10,20 +10,17 @@ interface RenameViewOptions { autoSelect: boolean; title: string; text: string; - onCommit: (newValue: string) => any; - onCancel: () => any; + onCommit?: (newValue: string) => any; + onCancel?: () => any; /** A truthy string return indicates a validation error */ onValidate: (newValue: string) => string; - openFiles: string[]; - closedFiles: string[]; } -export class RenameView - extends view.View { +export class RenameView extends view.View { - private newNameEditor: EditorView; + private newNameEditor: EditorViewzz; private validationMessage: JQuery; - private fileCount: JQuery; + private panel: AtomCore.Panel; private title: JQuery; static content = html; @@ -62,43 +59,65 @@ export class RenameView }); } - public editorAtRenameStart: AtomCore.IEditor = null; + public setPanel(panel: AtomCore.Panel) { + this.panel = panel + } + + public editorAtRenameStart?: AtomCore.IEditor; public clearView() { if (this.editorAtRenameStart && !this.editorAtRenameStart.isDestroyed()) { var view = atom.views.getView(this.editorAtRenameStart); view.focus(); } - panel.hide(); + this.panel.hide(); this.options = {}; - this.editorAtRenameStart = null; + this.editorAtRenameStart = undefined; } - public renameThis(options: RenameViewOptions) { + private renameThis(options: RenameViewOptions) { this.options = options; this.editorAtRenameStart = atom.workspace.getActiveTextEditor(); - panel.show(); + this.panel.show(); this.newNameEditor.model.setText(options.text); if (this.options.autoSelect) { this.newNameEditor.model.selectAll(); } else { - this.newNameEditor.model.moveToEndOfScreenLine(); + this.newNameEditor.model.moveCursorToEndOfScreenLine(); } this.title.text(this.options.title); this.newNameEditor.focus(); this.validationMessage.hide(); + } - this.fileCount.html(`
    - Files Counts: Already Open ( ${options.openFiles.length} ) and Currently Closed ( ${options.closedFiles.length} ) -
    `); + // Show the dialog and resolve the promise with the entered string + showRenameDialog(options: RenameViewOptions): Promise { + return new Promise((resolve, reject) => { + this.renameThis({ + ...options, + onCancel: reject, + onCommit: resolve + }) + }) } } -export var panelView: RenameView; -var panel: AtomCore.Panel; -export function attach() { - panelView = new RenameView({}); - panel = atom.workspace.addModalPanel({ item: panelView, priority: 1000, visible: false }); +export function attach(): {dispose(): void, renameView: RenameView} { + const renameView = new RenameView({}); + const panel = atom.workspace.addModalPanel({ + item: renameView, + priority: 1000, + visible: false + }) + + renameView.setPanel(panel) + + return { + dispose() { + console.log("TODO: Detach the rename view: ", panel) + }, + renameView + } } diff --git a/lib/main/atom/views/semanticView.tsx b/lib/main/atom/views/semanticView.tsx deleted file mode 100644 index b19b4b732..000000000 --- a/lib/main/atom/views/semanticView.tsx +++ /dev/null @@ -1,188 +0,0 @@ -import atomConfig = require("../atomConfig"); -import atomUtils = require("../atomUtils"); -import {uriForPath} from "../atomUtils"; -import * as sp from "atom-space-pen-views"; -import * as view from "./view"; -import React = require('react'); -import * as parent from "../../../worker/parent"; - -/** - * Eventually - */ -namespace rts { - /** 0 based length */ - export function indent(indent: number) { - return Array(indent + 1).join().split('').map(i => "\u00a0\u00a0\u00a0\u00a0"); - } -} - -interface Props { -} -interface State { - editor?: AtomCore.IEditor; - tree?: SemanticTreeNode[]; -} - -class MyComponent extends React.Component{ - constructor(props: Props) { - super(props); - - this.state = { - tree: [] - }; - } - - componentDidMount() { - // We listen to a few things - - // Editor scrolling - var editorScrolling: AtomCore.Disposable; - // Editor changing - var editorChanging: AtomCore.Disposable; - - let subscribeToEditor = (editor: AtomCore.IEditor) => { - this.setState({editor}); - - parent.getSemtanticTree({ filePath: editor.getPath() }).then((res) => { - this.setState({tree:res.nodes}); - }); - - // Subscribe to stop scrolling - editorScrolling = editor.onDidChangeCursorPosition(() => { - this.forceUpdate(); - }); - - // Subscribe to stop changing - editorChanging = editor.onDidStopChanging(() => { - parent.getSemtanticTree({ filePath: editor.getPath() }).then((res) => { - this.setState({tree:res.nodes}); - }); - }); - - panel.show(); - } - - let unsubscribeToEditor = () => { - panel.hide(); - this.setState({tree:[]}); - if (!this.state.editor) return; - - editorScrolling.dispose(); - editorChanging.dispose(); - this.forceUpdate(); - } - - // We don't start unless there is work to do ... so work - subscribeToEditor(atomUtils.getActiveEditor()); - - // Tab changing - atom.workspace.onDidChangeActivePaneItem((editor: AtomCore.IEditor) => { - if (atomUtils.onDiskAndTs(editor) && atomConfig.showSemanticView) { - subscribeToEditor(editor); - } - else { - unsubscribeToEditor(); - } - }); - } - - /** - * Actually component will never unmount ... so no unsubs for now - */ - componentWillUnmount() { - } - whileRendering = { - lastCursorLine: null as number - } - render() { - this.whileRendering = { - lastCursorLine: this.state.editor && this.state.editor.getLastCursor() ? this.state.editor.getLastCursor().getBufferRow() : null - }; - return
    - {this.state.tree.map(node => this.renderNode(node, 0)) } -
    ; - } - - renderNode(node: SemanticTreeNode, indent: number) { - return
    {this.gotoNode(node); event.stopPropagation();} } data-start={node.start.line} data-end={node.end.line}> - {rts.indent(indent) } - {node.text} - {node.subNodes.map(sn=> this.renderNode(sn, indent + 1)) } -
    - } - - getIconForKind(kind: string) { - return `icon icon-${kind}`; - } - isSelected(node: SemanticTreeNode) { - if (this.whileRendering.lastCursorLine == null) return ''; - else { - if (node.start.line <= this.whileRendering.lastCursorLine && node.end.line >= this.whileRendering.lastCursorLine) { - return 'selected'; - } - return ''; - } - } - gotoNode(node: SemanticTreeNode) { - var gotoLine = node.start.line; - this.state.editor.setCursorBufferPosition([gotoLine, 0]); - } -} - -export class SemanticView extends sp.ScrollView { - - public mainContent: JQuery; - public get rootDomElement() { - return this.mainContent[0]; - } - static content() { - return this.div({ class: 'atomts atomts-semantic-view native-key-bindings' }, () => { - this.div({ outlet: 'mainContent', class: 'layout vertical' }); - }); - } - - constructor(public config) { - super(config); - } - - /** - * This function exists because the react component needs access to `panel` which needs access to `SemanticView`. - * So we lazily create react component after panel creation - */ - started = false - start() { - if (this.started) return; - this.started = true; - React.render(React.createElement(MyComponent, {}), this.rootDomElement); - } -} - - - -export var mainView: SemanticView; -var panel: AtomCore.Panel; -export function attach() { - - // Only attach once - if (mainView) { - return; - } - - mainView = new SemanticView({}); - panel = atom.workspace.addRightPanel({ item: mainView, priority: 1000, visible: atomConfig.showSemanticView && atomUtils.isActiveEditorOnDiskAndTs() }); - - if (panel.isVisible()) { - mainView.start(); - } -} - -export function toggle() { - if (panel.isVisible()) { - atomConfig.showSemanticView = (false); - panel.hide(); - } else { - atomConfig.showSemanticView = (true); - panel.show(); - mainView.start(); - } -} diff --git a/lib/main/atom/views/semanticViewGlobals.d.ts b/lib/main/atom/views/semanticViewGlobals.d.ts deleted file mode 100644 index 6a0096985..000000000 --- a/lib/main/atom/views/semanticViewGlobals.d.ts +++ /dev/null @@ -1,5 +0,0 @@ -declare module AtomCore { - export interface IEditor { - showSemanticView: boolean; - } -} diff --git a/lib/main/atom/views/simpleOverlaySelectionView.ts b/lib/main/atom/views/simpleOverlaySelectionView.ts deleted file mode 100644 index 8de3491a4..000000000 --- a/lib/main/atom/views/simpleOverlaySelectionView.ts +++ /dev/null @@ -1,95 +0,0 @@ -/** - * A functional form of the SelectListView - * Only one of these bad boys is allowed on the screen at one time - */ - -export interface SelectListViewOptions { - items: T[]; - /** everything except the `li` which is required and we add for you */ - viewForItem: (item: T) => string; - - /** some property on item */ - filterKey: string; - confirmed: (item: T) => any; -} - -var singleton: SimpleOverlaySelectListView; - -export default function (options: SelectListViewOptions, editor: AtomCore.IEditor): SimpleOverlaySelectListView { - if (!singleton) singleton = new SimpleOverlaySelectListView(options, editor); - else { - singleton.options = options; - singleton.editor = editor; - } - - singleton.setItems(); - singleton.show(); - return singleton; -} - -/** - * Various Utility section - */ - -import sp = require('atom-space-pen-views'); -import * as atomUtils from "../atomUtils"; - -export class SimpleOverlaySelectListView extends sp.SelectListView { - - private _overlayDecoration: AtomCore.Decoration; - - - constructor(public options: SelectListViewOptions, public editor: AtomCore.IEditor) { - super(); - - this.$.addClass('atomts-overlay'); - (this.filterEditorView).model.placeholderText = 'Filter list'; - } - - get $(): JQuery { - return this; - } - - public setItems() { - super.setItems(this.options.items) - } - - /** override */ - viewForItem(item: T) { - return `
  • - ${this.options.viewForItem(item) } -
  • `; - } - - /** override */ - confirmed(item: T) { - this.options.confirmed(item); - this.hide(); - } - - /** override */ - getFilterKey() { - return this.options.filterKey; - } - - show() { - this.storeFocusedElement(); - this._overlayDecoration = this.editor.decorateMarker(this.editor.getLastCursor().getMarker(), - { type: "overlay", position: "tail", item: this }); - - /** I've need to do this timeout otherwise we don't get focus. I suspect its an artifact of creating an overlay decoration */ - // Comment this out if you want to test styles ;) - setTimeout(() => this.focusFilterEditor(), 100); - } - - hide() { - this.restoreFocus(); - - if (this._overlayDecoration) - this._overlayDecoration.destroy(); - } - - cancelled() { - this.hide(); - } -} diff --git a/lib/main/atom/views/simpleSelectionView.ts b/lib/main/atom/views/simpleSelectionView.ts index f1538bbab..27f32e2c4 100644 --- a/lib/main/atom/views/simpleSelectionView.ts +++ b/lib/main/atom/views/simpleSelectionView.ts @@ -30,7 +30,6 @@ export function simpleSelectionView(options: SelectListViewOptions): Simpl import sp = require('atom-space-pen-views'); import $ = sp.$; -import * as atomUtils from "../atomUtils"; export class SimpleSelectListView extends sp.SelectListView { @@ -58,7 +57,7 @@ export class SimpleSelectListView extends sp.SelectListView { return $('
  • ').append(view); }; } - + /** override */ confirmed(item: T) { this.options.confirmed(item); @@ -70,22 +69,24 @@ export class SimpleSelectListView extends sp.SelectListView { return this.options.filterKey; } - panel: AtomCore.Panel = null; + panel?: AtomCore.Panel; show() { this.storeFocusedElement(); if (!this.panel) this.panel = atom.workspace.addModalPanel({ item: this }); this.panel.show() - this.focusFilterEditor(); + this.focusFilterEditor(); // debugger; // DEBUG: the UI in the inspector so that it doesn't change on you } hide() { - this.panel.hide(); - this.restoreFocus(); + if (this.panel) { + this.panel.hide() + } + + this.restoreFocus() } cancelled() { this.hide(); } } - diff --git a/lib/main/atom/views/tooltipView.ts b/lib/main/atom/views/tooltipView.ts index 5e19728c0..93a8129c6 100644 --- a/lib/main/atom/views/tooltipView.ts +++ b/lib/main/atom/views/tooltipView.ts @@ -33,7 +33,7 @@ export class TooltipView extends view.View { var offset = 10; var left = this.rect.right; var top = this.rect.bottom; - var right = undefined; + var right: number | undefined = undefined; // X axis adjust if (left + this.$[0].offsetWidth >= view.$(document.body).width()) diff --git a/lib/main/atom/views/typeOverlayView.ts b/lib/main/atom/views/typeOverlayView.ts deleted file mode 100644 index db78ce505..000000000 --- a/lib/main/atom/views/typeOverlayView.ts +++ /dev/null @@ -1,20 +0,0 @@ -import escapeHtml = require('escape-html'); - -export function create(type, comment) { - let overlayHTML = ` - ${escapeHtml(type)} - `; - if (comment) { - overlayHTML += ` -
    -
    - ${escapeHtml(comment).replace(/(?:\r\n|\r|\n)/g, '
    ')} -
    - `; - } - - const overlay = document.createElement('div'); - overlay.className = 'atomts-show-type-view'; - overlay.innerHTML = overlayHTML; - return overlay; -} diff --git a/lib/main/atom/views/view.ts b/lib/main/atom/views/view.ts index 6327bd67d..2f32a11ce 100644 --- a/lib/main/atom/views/view.ts +++ b/lib/main/atom/views/view.ts @@ -1,5 +1,3 @@ - - import sp = require("atom-space-pen-views"); export class View extends sp.View { @@ -34,4 +32,4 @@ export class ScrollView extends sp.ScrollView { this.init(); } init() { } -} \ No newline at end of file +} diff --git a/lib/main/atomts.ts b/lib/main/atomts.ts index 5a53d5b15..4a80c1ae6 100644 --- a/lib/main/atomts.ts +++ b/lib/main/atomts.ts @@ -1,344 +1,214 @@ -import atomConfig = require('./atom/atomConfig'); -import {makeTsGlobal} from "../typescript/makeTypeScriptGlobal"; -makeTsGlobal(atomConfig.typescriptServices); - -import path = require('path'); -import fs = require('fs'); -import os = require('os'); - -import {errorView} from "./atom/views/mainPanelView"; - -///ts:import=autoCompleteProvider -import autoCompleteProvider = require('./atom/autoCompleteProvider'); ///ts:import:generated -///ts:import=tooltipManager -import tooltipManager = require('./atom/tooltipManager'); ///ts:import:generated -///ts:import=signatureProvider -import signatureProvider = require('./atom/signatureProvider'); ///ts:import:generated -///ts:import=atomUtils -import atomUtils = require('./atom/atomUtils'); ///ts:import:generated -import commands = require("./atom/commands/commands"); -///ts:import=onSaveHandler -import onSaveHandler = require('./atom/onSaveHandler'); ///ts:import:generated -///ts:import=debugAtomTs -import debugAtomTs = require('./atom/debugAtomTs'); ///ts:import:generated -///ts:import=typescriptGrammar -import typescriptGrammar = require('./atom/typescriptGrammar'); ///ts:import:generated -import _atom = require('atom'); -import {$} from "atom-space-pen-views"; - -import documentationView = require('./atom/views/documentationView'); -import renameView = require('./atom/views/renameView'); -import mainPanelView = require("./atom/views/mainPanelView"); -import * as semanticView from "./atom/views/semanticView"; -import {getFileStatus} from "./atom/fileStatusCache"; - -import editorSetup = require("./atom/editorSetup"); +import * as Atom from "atom" +import * as tsconfig from "tsconfig/dist/tsconfig" +import {attach as attachRenameView} from './atom/views/renameView' +import {AutocompleteProvider} from './atom/autoCompleteProvider' +import {ClientResolver} from "../client/clientResolver" +import {CompositeDisposable} from "atom" +import {debounce} from "lodash" +import {ErrorPusher} from "./errorPusher" +import {flatten, values} from "lodash" +import {LinterRegistry, Linter} from "../typings/linter" +import {StatusBar} from "../typings/status_bar" +import {StatusPanel} from "./atom/components/statusPanel" +import {TypescriptEditorPane} from "./typescriptEditorPane" +import {TypescriptBuffer} from "./typescriptBuffer" // globals -var statusBar; -var statusBarMessage; -var editorWatch: AtomCore.Disposable; -var autoCompleteWatch: AtomCore.Disposable; +const subscriptions = new CompositeDisposable() +export const clientResolver = new ClientResolver() +const panes: TypescriptEditorPane[] = [] -export interface PackageState { -} +// Register all custom components +import "./atom/components" +import {registerCommands} from "./atom/commands" + +let linter: Linter +let statusBar: StatusBar -import parent = require('../worker/parent'); +interface PackageState {} -// Export config -export var config = atomConfig.schema; -import {debounce} from "./lang/utils"; +export function activate(state: PackageState) { + require('atom-package-deps').install('atom-typescript', true).then(() => { -var hideIfNotActiveOnStart = debounce(() => { - // Only show if this editor is active: - var editor = atom.workspace.getActiveTextEditor(); - if (!atomUtils.onDiskAndTsRelated(editor)) { - mainPanelView.hide(); + let statusPriority = 100 + for (const panel of statusBar.getRightTiles()) { + if (panel.getItem().tagName === "GRAMMAR-SELECTOR-STATUS") { + statusPriority = panel.getPriority() - 1 + } } -}, 100); + // Add the rename view + const {renameView} = attachRenameView() + const statusPanel = StatusPanel.create() + + statusBar.addRightTile({ + item: statusPanel, + priority: statusPriority + }) + + subscriptions.add(statusPanel) + const errorPusher = new ErrorPusher() + errorPusher.setUnusedAsInfo(atom.config.get("atom-typescript.unusedAsInfo")) + subscriptions.add(atom.config.onDidChange("atom-typescript.unusedAsInfo", + (val: {oldValue: boolean, newValue: boolean}) => { + errorPusher.setUnusedAsInfo(val.newValue) + } + )) + + clientResolver.on("pendingRequestsChange", () => { + const pending = flatten(values(clientResolver.clients).map(cl => cl.pending)) + statusPanel.setPending(pending) + }) + + if (linter) { + errorPusher.setLinter(linter) + + clientResolver.on("diagnostics", ({type, filePath, diagnostics}) => { + errorPusher.setErrors(type, filePath, diagnostics) + }) + } -var __onlyOnce = false; -function onlyOnceStuff() { - if (__onlyOnce) return; - else __onlyOnce = true; + // Register the commands + registerCommands({ + clearErrors() { + errorPusher.clear() + }, + getTypescriptBuffer, + async getClient(filePath: string) { + const pane = panes.find(pane => pane.filePath === filePath) + if (pane) { + return pane.client + } - mainPanelView.attach(); + return clientResolver.get(filePath) + }, + renameView, + statusPanel, + }) - // Add the documentation view - documentationView.attach(); + let activePane: TypescriptEditorPane | undefined - // Add the rename view - renameView.attach(); + const onSave = debounce((pane: TypescriptEditorPane) => { + if (!pane.client) + return - semanticView.attach(); -} + const files = panes + .sort((a, b) => a.activeAt - b.activeAt) + .filter(_pane => _pane.filePath && _pane.isTypescript && _pane.client === pane.client) + .map(pane => pane.filePath) -/** only called once we have our dependencies */ -function readyToActivate() { - - // Start a ts worker - parent.startWorker(); - - // Load our custom code based grammar - // TODO: fix https://github.com/atom/atom/pull/6757 - // (atom).grammars.addGrammar(new typescriptGrammar.TypeScriptSemanticGrammar((atom).grammars)); - - // Streaming tests - /*for (var i = 0; i < 100; i++) { - (() => { - var index = i; - var repeat = index.toString() + ' '; - var message = ''; - for (var j = 0; j < 100; j++) { - message = message + repeat; - } - parent.echo({ echo: 'awesome ' + message, num: i }).then((res) => { - console.log('index: ' + index, res); - }); - })(); - }*/ - - // Observe changed active editor - atom.workspace.onDidChangeActivePaneItem((editor: AtomCore.IEditor) => { - if (atomUtils.onDiskAndTs(editor)) { - var filePath = editor.getPath(); - - onlyOnceStuff(); - parent.getProjectFileDetails({filePath}).then((res)=>{ - mainPanelView.panelView.setTsconfigInUse(res.projectFilePath); - }).catch(err=>{ - mainPanelView.panelView.setTsconfigInUse(''); - }); - - // Refresh errors stuff on change active tab. - // Because the fix might be in the other file - // or the other file might have made this file have an error - parent.errorsForFile({ filePath: filePath }) - .then((resp) => { - errorView.setErrors(filePath, resp.errors) - atomUtils.triggerLinter(); - }); - - mainPanelView.panelView.updateFileStatus(filePath); - mainPanelView.show(); - } - else if (atomUtils.onDiskAndTsRelated(editor)){ - mainPanelView.show(); - } - else { - mainPanelView.hide(); - } - }); - - // Observe editors loading - editorWatch = atom.workspace.observeTextEditors((editor: AtomCore.IEditor) => { - - // subscribe for tooltips - // inspiration : https://github.com/chaika2013/ide-haskell - var editorView = $(atom.views.getView(editor)); - tooltipManager.attach(editorView, editor); - - var filePath = editor.getPath(); - var ext = path.extname(filePath); - if (atomUtils.isAllowedExtension(ext)) { - let isTst = ext === '.tst'; - try { - // Only once stuff - onlyOnceStuff(); - parent.getProjectFileDetails({filePath}).then((res)=>{ - mainPanelView.panelView.setTsconfigInUse(res.projectFilePath); - }).catch(err=>{ - mainPanelView.panelView.setTsconfigInUse(''); - }); - - // We only do analysis once the file is persisted to disk - var onDisk = false; - if (fs.existsSync(filePath)) { - onDisk = true; - } - - // Setup the TS reporter: - hideIfNotActiveOnStart(); - - debugAtomTs.runDebugCode({ filePath, editor }); - - if (onDisk) { - - // Set errors in project per file - parent.updateText({ filePath: filePath, text: editor.getText() }) - .then(() => parent.errorsForFile({ filePath: filePath })) - .then((resp) => errorView.setErrors(filePath, resp.errors)); - - // Comparing potential emit to the existing js file - parent.getOutputJsStatus({ filePath: filePath }).then((res) => { - let status = getFileStatus(filePath); - status.emitDiffers = res.emitDiffers; - - // Update status if the file compared above is currently in the active editor - let ed = atom.workspace.getActiveTextEditor(); - if (ed && ed.getPath() === filePath) { - mainPanelView.panelView.updateFileStatus(filePath); - } - }); - } - - // Setup additional observers on the editor - editorSetup.setupEditor(editor); - - // Observe editors changing - var changeObserver = editor.onDidStopChanging(() => { - - // The condition is required because on initial load this event fires - // on every opened file, not just the active one - if (editor === atom.workspace.getActiveTextEditor()) { - let status = getFileStatus(filePath); - status.modified = editor.isModified(); - mainPanelView.panelView.updateFileStatus(filePath); - } - - // If the file isn't saved and we just show an error to guide the user - if (!onDisk) { - var root = { line: 0, col: 0 }; - errorView.setErrors(filePath, - [{ startPos: root, endPos: root, filePath: filePath, message: "Please save file for it be processed by TypeScript", preview: "" }] - ); - return; - } - - // Set errors in project per file - parent.errorsForFile({ filePath: filePath }) - .then((resp) => errorView.setErrors(filePath, resp.errors)); - - // TODO: provide function completions - /*var position = atomUtils.getEditorPosition(editor); - signatureProvider.requestHandler({ - program: program, - editor: editor, - filePath: filePath, - position: position - });*/ - - }); - - var buffer = editor.buffer; - var fasterChangeObserver: AtomCore.Disposable = (editor.buffer).onDidChange((diff: { oldRange: TextBuffer.IRange; newRange: TextBuffer.IRange; oldText: string; newText: string }) => { - - //// For debugging - // console.log(buffer.characterIndexForPosition(diff.oldRange.start), buffer.characterIndexForPosition(diff.oldRange.end), diff.oldText, - // buffer.characterIndexForPosition(diff.newRange.start), buffer.characterIndexForPosition(diff.newRange.end), diff.newText); - //// Examples - //// 20 20 "aaaa" 20 20 "" - //// 23 23 "" 23 24 "a" - //// 20 20 "" 20 24 "aaaa" - // stack(); - - var newText = diff.newText; - var oldText = diff.oldText; - - var start = { line: diff.oldRange.start.row, col: diff.oldRange.start.column }; - var end = { line: diff.oldRange.end.row, col: diff.oldRange.end.column }; - - // use this for faster language service host - var promise = parent.editText({ filePath, start, end, newText }); - - // For debugging the language service going out of sync - // console.log(JSON.stringify({oldText,newText})); - // promise.then(() => { - // parent.debugLanguageServiceHostVersion({filePath:atom.workspace.getActiveTextEditor().getPath()}) - // .then((res)=>{ - // console.log(JSON.stringify({real:editor.buffer.getText()})); - // console.log(JSON.stringify({lang:res.text})); - // console.log(editor.getText() == res.text); - // }); - // }); - }); - - // Observe editors saving - var saveObserver = editor.onDidSave((event) => { - onDisk = true; - // If this is a saveAs event.path will be different so we should change it - filePath = event.path; - onSaveHandler.handle({ filePath: filePath, editor: editor }); - }); - - // Observe editors closing - var destroyObserver = editor.onDidDestroy(() => { - // Clear errors in view - errorView.setErrors(filePath, []); - - // Clear editor observers - changeObserver.dispose(); - fasterChangeObserver.dispose(); - saveObserver.dispose(); - destroyObserver.dispose(); - }); - - } catch (ex) { - console.error('Solve this in atom-typescript', ex); - throw ex; - } - } - }); + pane.client.executeGetErr({files, delay: 100}) - // Register the commands - commands.registerCommands(); -} + }, 50) -export function activate(state: PackageState) { - require('atom-package-deps').install('atom-typescript').then(waitForGrammarActivation).then(readyToActivate) + subscriptions.add(atom.workspace.observeTextEditors((editor: AtomCore.IEditor) => { + panes.push(new TypescriptEditorPane(editor, { + getClient: (filePath: string) => clientResolver.get(filePath), + onDispose(pane) { + if (activePane === pane) { + activePane = undefined + } + + panes.splice(panes.indexOf(pane), 1) + + // Clear errors if any from this pane + errorPusher.setErrors("syntaxDiag", pane.filePath, []) + errorPusher.setErrors("semanticDiag", pane.filePath, []) + }, + onSave, + statusPanel, + })) + })) + + activePane = panes.find(pane => pane.editor === atom.workspace.getActiveTextEditor()) + + if (activePane) { + activePane.onActivated() + } + + subscriptions.add(atom.workspace.onDidChangeActivePaneItem((editor: AtomCore.IEditor) => { + if (activePane) { + activePane.onDeactivated() + activePane = undefined + } + + if (atom.workspace.isTextEditor(editor)) { + const pane = panes.find(pane => pane.editor === editor) + if (pane) { + activePane = pane + pane.onActivated() + } + } + })) + }) } export function deactivate() { - if (statusBarMessage) statusBarMessage.destroy(); - if (editorWatch) editorWatch.dispose(); - if (autoCompleteWatch) autoCompleteWatch.dispose(); - - parent.stopWorker(); + subscriptions.dispose() } export function serialize(): PackageState { - return {}; + return {} } -export function deserialize() { - /* do any tear down here */ +export function consumeLinter(registry: LinterRegistry) { + linter = registry.register({ + name: "Typescript" + }) } -// Registering an autocomplete provider -export function provide() { - return [autoCompleteProvider.provider]; +export function consumeStatusBar(_statusBar: StatusBar) { + statusBar = _statusBar } -import * as linter from "../linter"; -export function provideLinter() { - return linter.provider; +// Registering an autocomplete provider +export function provide() { + return [ + new AutocompleteProvider(clientResolver, {getTypescriptBuffer}), + ] } -export function consumeSnippets(snippetsManager) { - atomUtils._setSnippetsManager(snippetsManager); +export var config = { + unusedAsInfo: { + title: 'Show unused values with severity info', + description: 'Show unused values with severity \'info\' instead of \'error\'', + type: 'boolean', + default: true + } } -function waitForGrammarActivation(): Promise { - let activated = false; - const promise = new Promise((resolve,reject) => { - let editorWatch = atom.workspace.observeTextEditors((editor: AtomCore.IEditor) => { - - // Just so we won't attach more events than necessary - if (activated) return; - editor.observeGrammar((grammar: AtomCore.IGrammar) => { - if (grammar.packageName === 'atom-typescript') { - activated = true; - resolve({}); - editorWatch.dispose(); - } - }); - }); - }); - return promise; +export function loadProjectConfig(sourcePath: string): Promise { + return clientResolver.get(sourcePath).then(client => { + return client.executeProjectInfo({needFileNameList: false, file: sourcePath}).then(result => { + return tsconfig.load(result.body!.configFileName) + }) + }) } -import * as hyperclickProvider from "../hyperclickProvider"; -export function getHyperclickProvider() { - return hyperclickProvider; +// Get Typescript buffer for the given path +async function getTypescriptBuffer(filePath: string) { + const pane = panes.find(pane => pane.filePath === filePath) + if (pane) { + return { + buffer: pane.buffer, + isOpen: true + } + } + + // Wait for the buffer to load before resolving the promise + const buffer = await new Promise(resolve => { + const buffer = new Atom.TextBuffer({ + filePath, + load: true + }) + + buffer.onDidReload(() => { + resolve(buffer) + }) + }) + + return { + buffer: new TypescriptBuffer(buffer, filePath => clientResolver.get(filePath)), + isOpen: false + } } diff --git a/lib/main/bin/atbuild.ts b/lib/main/bin/atbuild.ts deleted file mode 100644 index b12784dc0..000000000 --- a/lib/main/bin/atbuild.ts +++ /dev/null @@ -1,44 +0,0 @@ -/** - * This file is a work in progress - */ - -import {makeTsGlobal} from "../../typescript/makeTypeScriptGlobal"; -makeTsGlobal(); - -import * as tsconfig from "../tsconfig/tsconfig"; -import * as building from "../lang/modules/building"; -import {Project} from "../lang/core/project"; -import {selectMany} from "../lang/utils"; - -var startLoc; -if (process.argv.length > 2) { - // Read the first additional argument passed to the program - startLoc = process.argv[2]; -} -else { - startLoc = process.cwd(); -} - -var projectFile = tsconfig.getProjectSync(startLoc); -console.log(`Compiling using project file: ${projectFile.projectFilePath}`); -var proj = new Project(projectFile); - -var errors = selectMany(proj.projectFile.project.files.map((filePath) => { - var output = building.emitFile(proj, filePath); - return output.errors; -})); - -// Also optionally emit a root dts: -building.emitDts(proj); - -if (errors.length == 0) { - console.log('Compile successfull'); - process.exit(0); -} -else { - console.log('Errors:'); - errors.forEach(e=> { - console.log(e.filePath, e.message); - }) - process.exit(1); -} \ No newline at end of file diff --git a/lib/main/errorPusher.ts b/lib/main/errorPusher.ts new file mode 100644 index 000000000..6f4da2a3a --- /dev/null +++ b/lib/main/errorPusher.ts @@ -0,0 +1,67 @@ +import {debounce} from "lodash" +import {Diagnostic} from "typescript/lib/protocol" +import {Linter, LinterMessage} from "../typings/linter" +import {locationsToRange, systemPath} from "./atom/utils" + +/** Class that collects errors from all of the clients and pushes them to the Linter service */ +export class ErrorPusher { + private linter?: Linter + private errors: Map> = new Map() + private unusedAsInfo = true + + /** Set errors. Previous errors with the same prefix and filePath are going to be replaced */ + setErrors(prefix: string | undefined, filePath: string | undefined, errors: Diagnostic[]) { + if (prefix == undefined || filePath == undefined) { + console.warn("setErrors: prefix or filePath is undefined", prefix, filePath) + return + } + + let prefixed = this.errors.get(prefix) + if (!prefixed) { + prefixed = new Map() + this.errors.set(prefix, prefixed) + } + + prefixed.set(filePath, errors) + + this.pushErrors() + } + + setUnusedAsInfo(unusedAsInfo: boolean) { + this.unusedAsInfo = unusedAsInfo + } + + /** Clear all errors */ + clear() { + if (this.linter) { + this.linter.deleteMessages() + } + } + + setLinter(linter: Linter) { + this.linter = linter + this.pushErrors() + } + + private pushErrors = debounce(() => { + const errors: LinterMessage[] = [] + + for (const fileErrors of this.errors.values()) { + for (const [filePath, diagnostics] of fileErrors) { + const _filePath = systemPath(filePath) + for (const diagnostic of diagnostics) { + errors.push({ + type: this.unusedAsInfo && diagnostic.code === 6133 ? "Info" : "Error", + text: diagnostic.text, + filePath: _filePath, + range: diagnostic.start ? locationsToRange(diagnostic.start, diagnostic.end) : undefined + }) + } + } + } + + if (this.linter) { + this.linter.setMessages(errors) + } + }, 100) +} diff --git a/lib/main/json2dts/json2dts.ts b/lib/main/json2dts/json2dts.ts deleted file mode 100644 index 136447696..000000000 --- a/lib/main/json2dts/json2dts.ts +++ /dev/null @@ -1,21 +0,0 @@ -var JSON2DTS = require("json2dts"); -var Json2dts = (JSON2DTS).Json2dts; -var toValidJSON = (JSON2DTS).toValidJSON; - -export function convert(content: string) { - try { - var converter = new Json2dts(); - var text2Obj = JSON.parse(toValidJSON(content)); - if (typeof text2Obj != "string") { - converter.parse(text2Obj, 'RootJson'); - content = converter.getCode(); - } - else { - atom.notifications.addError('Json2dts Invalid JSON'); - } - - } catch (e) { - atom.notifications.addError(`Json2dts Invalid JSON error: ${e}`); - } - return content; -} diff --git a/lib/main/lang/core/languageServiceHost2.ts b/lib/main/lang/core/languageServiceHost2.ts deleted file mode 100644 index 23ff618f0..000000000 --- a/lib/main/lang/core/languageServiceHost2.ts +++ /dev/null @@ -1,401 +0,0 @@ -import path = require('path'); -import utils = require('../utils'); -import fs = require('fs'); -import os = require('os') -import textBuffer = require('basarat-text-buffer'); - -import tsconfig = require('../../tsconfig/tsconfig'); -import {typescriptServices} from "../typescriptServices"; - -interface ScriptInfo { - getFileName(): string; - getContent(): string; - getVersion(): number; - getIsOpen(): boolean; - setIsOpen(val: boolean): void; - getEditRanges(): ts.TextChangeRange[]; - getLineStarts(): number[]; - - - updateContent(newContent: string): void; - editContent(minChar: number, limChar: number, newText: string): void; - getPositionFromLine(line: number, ch: number): number; - getLineAndColForPositon(position: number): EditorPosition; - getLinePreview(line: number): string; -} - -/** - * Allows you to easily create a "script snapshot" < which is something that the actual language service wants to work with - */ -function createScriptInfo(fileName: string, text: string, isOpen = false): ScriptInfo { - - - var version: number = 1; - var editRanges: ts.TextChangeRange[] = []; - - var _lineStarts: number[]; - var _lineStartIsDirty = true; - var buffer = new textBuffer(text); - - function getLineStarts() { - if (_lineStartIsDirty) { - // TODO: pref - _lineStarts = []; - var totalLength = 0; - buffer.lines.forEach((line, index) => { - _lineStarts.push(totalLength); - var lineLength = line.length; - totalLength = totalLength + lineLength + buffer.lineEndings[index].length; - }); - - _lineStartIsDirty = false; - } - return _lineStarts; - } - - /** - * update the content of the script - * - * @param newContent the new script content - */ - function updateContent(newContent: string): void { - buffer = new textBuffer(newContent); - _lineStartIsDirty = true; - editRanges = []; - version++; - } - - - /** - * edit the script content - * - * @param minChar the index in the file content where the edition begins - * @param limChar the index in the file content where the edition ends - * @param newText the text inserted - */ - function editContent(minChar: number, limChar: number, newText: string): void { - - // Apply edits - var start = getLineAndColForPositon(minChar); - var end = getLineAndColForPositon(limChar); - - // console.error('initial text:',buffer.getText()==newText); - // console.error({minChar,limChar,newText:newText.length}); - // console.error(start,end); - buffer.setTextInRange([[start.line, start.col], [end.line, end.col]], newText, {normalizeLineEndings: false}); - // console.error(buffer.getText().length); - // console.error(JSON.stringify({newText, final:buffer.getText()})); - - _lineStartIsDirty = true; - - // Store edit range + new length of script - editRanges.push({ - span: { start: minChar, length: limChar - minChar }, - newLength: newText.length - }); - - // Update version # - version++; - } - - - - /** - * return an index position from line an character position - * - * @param line line number - * @param character charecter poisiton in the line - */ - function getPositionFromLine(line: number, ch: number) { - return buffer.characterIndexForPosition([line, ch]); - } - - /** - * return line and chararacter position from index position - * - * @param position - */ - function getLineAndColForPositon(position: number) { - var {row, column} = buffer.positionForCharacterIndex(position); - return { - line: row, - col: column - }; - } - - function getLinePreview(line: number) { - return (buffer.lines[line] || '').trim(); - } - - - return { - getFileName: () => fileName, - getContent: () => buffer.getText(), - getVersion: () => version, - getIsOpen: () => isOpen, - setIsOpen: val => isOpen = val, - getEditRanges: () => editRanges, - getLineStarts: getLineStarts, - - updateContent: updateContent, - editContent: editContent, - getPositionFromLine: getPositionFromLine, - getLineAndColForPositon: getLineAndColForPositon, - getLinePreview: getLinePreview - } -} - - - -function getScriptSnapShot(scriptInfo: ScriptInfo): ts.IScriptSnapshot { - var lineStarts = scriptInfo.getLineStarts(); - var textSnapshot = scriptInfo.getContent(); - var version = scriptInfo.getVersion() - var editRanges = scriptInfo.getEditRanges() - - - function getChangeRange(oldSnapshot: ts.IScriptSnapshot): ts.TextChangeRange { - var unchanged = { span: { start: 0, length: 0 }, newLength: 0 }; - - function collapseChangesAcrossMultipleVersions(changes: ts.TextChangeRange[]) { - if (changes.length === 0) { - return unchanged; - } - if (changes.length === 1) { - return changes[0]; - } - var change0 = changes[0]; - var oldStartN = change0.span.start; - var oldEndN = change0.span.start + change0.span.length; - var newEndN = oldStartN + change0.newLength; - for (var i = 1; i < changes.length; i++) { - var nextChange = changes[i]; - var oldStart1 = oldStartN; - var oldEnd1 = oldEndN; - var newEnd1 = newEndN; - var oldStart2 = nextChange.span.start; - var oldEnd2 = nextChange.span.start + nextChange.span.length; - var newEnd2 = oldStart2 + nextChange.newLength; - oldStartN = Math.min(oldStart1, oldStart2); - oldEndN = Math.max(oldEnd1, oldEnd1 + (oldEnd2 - newEnd1)); - newEndN = Math.max(newEnd2, newEnd2 + (newEnd1 - oldEnd2)); - } - return { span: { start: oldStartN, length: oldEndN - oldStartN }, newLength: newEndN - oldStartN }; - }; - - var scriptVersion: number = (oldSnapshot).version || 0; - if (scriptVersion === version) { - return unchanged; - } - var initialEditRangeIndex = editRanges.length - (version - scriptVersion); - - if (initialEditRangeIndex < 0) { - return null; - } - - var entries = editRanges.slice(initialEditRangeIndex); - return collapseChangesAcrossMultipleVersions(entries); - } - - return { - getText: (start: number, end: number) => textSnapshot.substring(start, end), - getLength: () => textSnapshot.length, - getChangeRange: getChangeRange, - } -} - -function getTypescriptLocation() { - if (typescriptServices) { - return path.dirname(typescriptServices); - } - else { - return path.dirname(require.resolve('typescript')); - } -} - -export var getDefaultLibFilePath = (options: ts.CompilerOptions) => { - var filename = ts.getDefaultLibFileName(options); - return (path.join(getTypescriptLocation(), filename)).split('\\').join('/'); -} - -export var typescriptDirectory = getTypescriptLocation().split('\\').join('/'); - - -// NOTES: -// * fileName is * always * the absolute path to the file -// * content is *always* the string content of the file -export class LanguageServiceHost implements ts.LanguageServiceHost { - - /** - * a map associating file absolute path to ScriptInfo - */ - fileNameToScript: { [fileName: string]: ScriptInfo } = Object.create(null); - - constructor(private config: tsconfig.TypeScriptProjectFileDetails) { - // Add the `lib.d.ts` - if (!config.project.compilerOptions.noLib && !config.project.compilerOptions.lib) { - this.addScript(getDefaultLibFilePath(config.project.compilerOptions)); - } - else if (Array.isArray(config.project.compilerOptions.lib)) { - for (let lib of config.project.compilerOptions.lib) { - let filename = "lib." + lib + ".d.ts"; - this.addScript((path.join(getTypescriptLocation(), filename)).split('\\').join('/')); - } - } - } - - addScript = (fileName: string, content?: string) => { - - - try { - if (!content) { - content = fs.readFileSync(fileName).toString(); - } - } - catch (ex) { // if we cannot read the file for whatever reason - // TODO: in next version of TypeScript langauge service we would add it with "undefined" - // For now its just an empty string - content = ''; - } - - var script = createScriptInfo(fileName, content); - this.fileNameToScript[fileName] = script; - } - - removeScript = (fileName: string) => { - delete this.fileNameToScript[fileName]; - } - - removeAll = () => { - this.fileNameToScript = Object.create(null); - } - - updateScript = (fileName: string, content: string) => { - var script = this.fileNameToScript[fileName]; - if (script) { - script.updateContent(content); - return; - } - else { - this.addScript(fileName, content); - } - } - - editScript = (fileName: string, start: EditorPosition, end: EditorPosition, newText: string) => { - var script = this.fileNameToScript[fileName]; - if (script) { - var minChar = script.getPositionFromLine(start.line, start.col); - var limChar = script.getPositionFromLine(end.line, end.col); - script.editContent(minChar, limChar, newText); - return; - } - - throw new Error('No script with name \'' + fileName + '\''); - } - - setScriptIsOpen = (fileName: string, isOpen: boolean) => { - var script = this.fileNameToScript[fileName]; - if (script) { - script.setIsOpen(isOpen); - return; - } - - throw new Error('No script with name \'' + fileName + '\''); - } - - getScriptContent = (fileName: string): string => { - var script = this.fileNameToScript[fileName]; - if (script) { - return script.getContent(); - } - return null; - } - - hasScript = (fileName: string) => { - return !!this.fileNameToScript[fileName]; - } - - getIndexFromPosition = (fileName: string, position: { col: number; line: number }): number => { - var script = this.fileNameToScript[fileName]; - if (script) { - return script.getPositionFromLine(position.line, position.col); - } - return -1; - } - - getPositionFromIndex = (fileName: string, index: number): { col: number; line: number } => { - if (!this.fileNameToScript[fileName]) this.addScript(fileName); - var script = this.fileNameToScript[fileName]; - if (script) { - return script.getLineAndColForPositon(index); - } - return null; - } - - getPositionFromTextSpanWithLinePreview = (fileName: string, textSpan: ts.TextSpan): { position: EditorPosition, preview: string } => { - var position = this.getPositionFromIndex(fileName, textSpan.start); - var script = this.fileNameToScript[fileName]; - var preview = script.getLinePreview(position.line); - - return { preview, position }; - } - - //////////////////////////////////////// - // ts.LanguageServiceHost implementation - //////////////////////////////////////// - - getCompilationSettings = () => this.config.project.compilerOptions; - getNewLine = () => { - let eol = os.EOL; - switch (this.config.project.compilerOptions.newLine) { - case ts.NewLineKind.CarriageReturnLineFeed: - eol = "\r\n"; - break; - case ts.NewLineKind.LineFeed: - eol = "\n"; - break; - } - return eol; - } - getScriptFileNames = (): string[]=> Object.keys(this.fileNameToScript); - getScriptVersion = (fileName: string): string => { - var script = this.fileNameToScript[fileName]; - if (script) { - return '' + script.getVersion(); - } - return '0'; - } - getScriptIsOpen = (fileName: string): boolean => { - var script = this.fileNameToScript[fileName]; - if (script) { - return script.getIsOpen(); - } - return false; - } - getScriptSnapshot = (fileName: string): ts.IScriptSnapshot => { - var script = this.fileNameToScript[fileName]; - if (script) { - return getScriptSnapShot(script); - } - // This script should be a part of the project if it exists - else if(this.fileExists(fileName)){ - this.config.project.files.push(fileName); - this.addScript(fileName); - return this.getScriptSnapshot(fileName); - } - return null; - } - getCurrentDirectory = (): string => { - return this.config.projectFileDirectory; - } - getDefaultLibFileName = ts.getDefaultLibFileName; - - fileExists = (path: string) => { - try { - const stat = fs.statSync(path) - return stat.isFile() - } catch (error) { - return false - } - } -} diff --git a/lib/main/lang/core/project.ts b/lib/main/lang/core/project.ts deleted file mode 100644 index fd0b82e53..000000000 --- a/lib/main/lang/core/project.ts +++ /dev/null @@ -1,57 +0,0 @@ - - -import path = require('path'); -import fs = require('fs'); -import os = require('os'); - -export import languageServiceHost = require('./languageServiceHost2'); -import tsconfig = require('../../tsconfig/tsconfig'); -import utils = require('../utils'); -import * as transformerRegistry from "../transformers/transformerRegistry"; - -/** - * Wraps up `langaugeService` `languageServiceHost` and `projectFile` in a single package - */ -export class Project { - public languageServiceHost: languageServiceHost.LanguageServiceHost; - public languageService: ts.LanguageService; - - constructor(public projectFile: tsconfig.TypeScriptProjectFileDetails) { - this.languageServiceHost = new languageServiceHost.LanguageServiceHost(projectFile); - var transformerRegexes = transformerRegistry.getRegexes(); - - // Add all the files - projectFile.project.files.forEach((file) => { - if (tsconfig.endsWith(file, '.tst.ts')) { - // initially add without transform sections. - var rawContent = fs.readFileSync(tsconfig.removeExt(file), 'utf-8'); - - var withoutTransform = rawContent; - transformerRegexes.forEach(transformer => { - withoutTransform = withoutTransform.replace(transformer, '');; - }); - - this.languageServiceHost.addScript(file, withoutTransform); - // TODO: update with transform sections - } - else { - this.languageServiceHost.addScript(file); - } - }); - - - this.languageService = ts.createLanguageService(this.languageServiceHost, ts.createDocumentRegistry()); - } - - /** all files except lib.d.ts */ - public getProjectSourceFiles(): ts.SourceFile[] { - var libFile = languageServiceHost.getDefaultLibFilePath(this.projectFile.project.compilerOptions); - var files - = this.languageService.getProgram().getSourceFiles().filter(x=> x.fileName !== libFile); - return files; - } - - public includesSourceFile(fileName: string) { - return (this.getProjectSourceFiles().filter((f) => f.fileName === fileName).length === 1); - } -} diff --git a/lib/main/lang/fixmyts/astUtils.ts b/lib/main/lang/fixmyts/astUtils.ts deleted file mode 100644 index 8a2348116..000000000 --- a/lib/main/lang/fixmyts/astUtils.ts +++ /dev/null @@ -1,117 +0,0 @@ - -export var forEachChild = ts.forEachChild; - -export function forEachChildRecursive(node: ts.Node, cbNode: (node: ts.Node, depth: number) => T, depth = 0): T { - var res = cbNode(node, depth); - forEachChildRecursive(node, cbNode, depth + 1); - return res; -} - -/** Number to string */ -export function syntaxKindToString(syntaxKind: ts.SyntaxKind): string { - return (ts).SyntaxKind[syntaxKind]; -} - -export function getNodeByKindAndName(program: ts.Program, kind: ts.SyntaxKind, name: string): ts.Node { - let found: ts.Node = undefined; - - function findNode(node: ts.Node) { - if (node.kind == kind) { - // Now lookup name: - if (node.kind == ts.SyntaxKind.ClassDeclaration) { - if ((node).name.text == name) { - found = node; - } - } - if (node.kind == ts.SyntaxKind.InterfaceDeclaration) { - if ((node).name.text == name) { - found = node; - } - } - } - - if (!found) { forEachChild(node, findNode); } - } - - for (let file of program.getSourceFiles()) { - forEachChild(file, findNode); - } - - return found; -} - - -export function getSourceFileImports(srcFile: ts.SourceFile): string[] { - var modules: string[] = []; - getImports(srcFile, modules); - return modules; -} - -/** - * For example for import path + the string inside that - */ -interface StringWithRange { - text: string; - range: ts.TextRange; -} - -export function getSourceFileImportsWithTextRange(srcFile: ts.SourceFile) - : StringWithRange[] { - var modules: StringWithRange[] = []; - getImportsWithTextRange(srcFile, modules); - return modules; -} - - -// https://github.com/Microsoft/TypeScript/issues/2621#issuecomment-90986004 -function getImports(searchNode: ts.Node, importedModules: string[]) { - ts.forEachChild(searchNode, node => { - // Vist top-level import nodes - if (node.kind === ts.SyntaxKind.ImportDeclaration || node.kind === ts.SyntaxKind.ImportEqualsDeclaration || node.kind === ts.SyntaxKind.ExportDeclaration) { - let moduleNameExpr = getExternalModuleName(node); - // if they have a name, that is a string, i.e. not alias defition `import x = y` - if (moduleNameExpr && moduleNameExpr.kind === ts.SyntaxKind.StringLiteral) { - importedModules.push((moduleNameExpr).text); - } - } - else if (node.kind === ts.SyntaxKind.ModuleDeclaration && (node).name.kind === ts.SyntaxKind.StringLiteral) { - // Ambient module declaration - getImports((node).body, importedModules); - } - }); -} -function getExternalModuleName(node: ts.Node): ts.Expression { - if (node.kind === ts.SyntaxKind.ImportDeclaration) { - return (node).moduleSpecifier; - } - if (node.kind === ts.SyntaxKind.ImportEqualsDeclaration) { - let reference = (node).moduleReference; - if (reference.kind === ts.SyntaxKind.ExternalModuleReference) { - return (reference).expression; - } - } - if (node.kind === ts.SyntaxKind.ExportDeclaration) { - return (node).moduleSpecifier; - } -} -/** Note: we exclude the quote characters */ -function getImportsWithTextRange(searchNode: ts.Node, importedModules: StringWithRange[]) { - ts.forEachChild(searchNode, node => { - // Vist top-level import nodes - if (node.kind === ts.SyntaxKind.ImportDeclaration || node.kind === ts.SyntaxKind.ImportEqualsDeclaration || node.kind === ts.SyntaxKind.ExportDeclaration) { - let moduleNameExpr = getExternalModuleName(node); - // if they have a name, that is a string, i.e. not alias defition `import x = y` - if (moduleNameExpr && moduleNameExpr.kind === ts.SyntaxKind.StringLiteral) { - let moduleExpr = moduleNameExpr; - importedModules.push({ - text: moduleExpr.text, - range: { pos: moduleExpr.getStart() + 1, end: moduleExpr.getEnd() - 1 } - }); - } - } - else if (node.kind === ts.SyntaxKind.ModuleDeclaration && (node).name.kind === ts.SyntaxKind.StringLiteral) { - // Ambient module declaration - getImportsWithTextRange((node).body, importedModules); - } - }); -} diff --git a/lib/main/lang/fixmyts/quickFix.ts b/lib/main/lang/fixmyts/quickFix.ts deleted file mode 100644 index 12d0ccccb..000000000 --- a/lib/main/lang/fixmyts/quickFix.ts +++ /dev/null @@ -1,79 +0,0 @@ -/** - * Interfaces for quick fixes - */ -import project = require("../core/project"); - - - -export interface Refactoring extends ts.TextChange { - filePath: string; - - /** If you want to insert a snippet. Be careful that you shouldn't return more than one refatoring if you want to use this */ - isNewTextSnippet?: boolean; -} - - -/** Note this interface has a few redundant stuff. This is intentional to precompute once */ -export interface QuickFixQueryInformation { - project: project.Project; - service: ts.LanguageService; - program: ts.Program; - typeChecker: ts.TypeChecker; - sourceFile: ts.SourceFile; - sourceFileText: string; - fileErrors: ts.Diagnostic[]; - positionErrors: ts.Diagnostic[]; - positionErrorMessages: string[]; - position: number; - positionNode: ts.Node; - filePath: string; - - /** - * Either the previous or the current. - * This needs more thinking e.g. 'rename' already does the right thing. See how it is implemented - */ - oneOfPositionNodesOfType?(kind: ts.SyntaxKind): boolean; -} - -export interface CanProvideFixResponse { - /** - * Return '' if you can't provide a fix - * return 'Some string to display' if you can provide a string - */ - display: string; - isNewTextSnippet?: boolean; -} - -export interface QuickFix { - /** Some unique key. Classname works best ;) */ - key: string; - - canProvideFix(info: QuickFixQueryInformation): CanProvideFixResponse; - - provideFix(info: QuickFixQueryInformation): Refactoring[]; -} - - -/** You don't need to create this manually. Just use the util function */ -export interface RefactoringsByFilePath { - [filePath: string]: Refactoring[]; -} - -/** Utility method. Reason is we want to transact by file path */ -export function getRefactoringsByFilePath(refactorings: Refactoring[]) { - var loc: RefactoringsByFilePath = {}; - for (let refac of refactorings) { - if (!loc[refac.filePath]) loc[refac.filePath] = []; - loc[refac.filePath].push(refac); - } - - // sort each of these in descending by start location - for (let filePath in loc) { - let refactorings = loc[filePath]; - refactorings.sort((a: Refactoring, b: Refactoring) => { - return (b.span.start - a.span.start); - }); - } - - return loc; -} diff --git a/lib/main/lang/fixmyts/quickFixRegistry.ts b/lib/main/lang/fixmyts/quickFixRegistry.ts deleted file mode 100644 index c31e3f378..000000000 --- a/lib/main/lang/fixmyts/quickFixRegistry.ts +++ /dev/null @@ -1,36 +0,0 @@ -import {QuickFix} from "./quickFix"; -/** - * This exists to register the quick fixes - */ -import {AddClassMember} from "./quickFixes/addClassMember"; -import {AddClassMethod} from "./quickFixes/addClassMethod"; -import {AddImportDefaultStatement} from "./quickFixes/addImportDefaultStatement"; -import {AddImportFromStatement} from "./quickFixes/addImportFromStatement"; -import {AddImportStatement} from "./quickFixes/addImportStatement"; -import {EqualsToEquals} from "./quickFixes/equalsToEquals"; -import {ExtractVariable} from "./quickFixes/extractVariable"; -import {WrapInProperty} from "./quickFixes/wrapInProperty"; -import {QuotesToQuotes} from "./quickFixes/quotesToQuotes"; -import {QuoteToTemplate} from "./quickFixes/quoteToTemplate"; -import {StringConcatToTemplate} from "./quickFixes/stringConcatToTemplate"; -import {TypeAssertPropertyAccessToAny} from "./quickFixes/typeAssertPropertyAccessToAny"; -import {TypeAssertPropertyAccessToType} from "./quickFixes/typeAssertPropertyAccessToType"; -import {ImplementInterface} from "./quickFixes/implementInterface"; -import {SingleLineCommentToJsdoc} from "./quickFixes/singleLineCommentToJsdoc"; -export var allQuickFixes: QuickFix[] = [ - new AddClassMethod(), - new AddClassMember(), - new AddImportDefaultStatement(), - new AddImportFromStatement(), - new AddImportStatement(), - new WrapInProperty(), - new EqualsToEquals(), - new ExtractVariable(), - new StringConcatToTemplate(), - new QuotesToQuotes(), - new QuoteToTemplate(), - new TypeAssertPropertyAccessToAny(), - new TypeAssertPropertyAccessToType(), - new ImplementInterface(), - new SingleLineCommentToJsdoc() -]; \ No newline at end of file diff --git a/lib/main/lang/fixmyts/quickFixes/addClassMember.ts b/lib/main/lang/fixmyts/quickFixes/addClassMember.ts deleted file mode 100644 index a990830dc..000000000 --- a/lib/main/lang/fixmyts/quickFixes/addClassMember.ts +++ /dev/null @@ -1,122 +0,0 @@ -import {QuickFix, QuickFixQueryInformation, Refactoring, CanProvideFixResponse} from "../quickFix"; -import * as ast from "../astUtils"; -import {EOL} from "os"; - -function getIdentifierAndClassNames(error: ts.Diagnostic) { - var errorText: string = error.messageText; - if (typeof errorText !== 'string') { - console.error('I have no idea what this is:', errorText); - return undefined; - }; - - // see https://github.com/Microsoft/TypeScript/blob/6637f49209ceb5ed719573998381eab010fa48c9/src/compiler/diagnosticMessages.json#L842 - var match = errorText.match(/Property \'(\w+)\' does not exist on type \'(\w+)\'./); - - // Happens when the type name is an alias. We can't refactor in this case anyways - if (!match) return; - - var [, identifierName, className] = match; - return { identifierName, className }; -} - -/** foo.a => a */ -function getLastNameAfterDot(text: string) { - return text.substr(text.lastIndexOf('.') + 1); -} - -function getTypeStringForNode(node: ts.Node, typeChecker: ts.TypeChecker) { - var type = typeChecker.getTypeAtLocation(node); - - /** Discoverd from review of `services.getQuickInfoAtPosition` */ - return ts.displayPartsToString(ts.typeToDisplayParts(typeChecker, type)).replace(/\s+/g, ' '); -} - -export class AddClassMember implements QuickFix { - key = AddClassMember.name; - - canProvideFix(info: QuickFixQueryInformation): CanProvideFixResponse { - var relevantError = info.positionErrors.filter(x=> x.code == ts.Diagnostics.Property_0_does_not_exist_on_type_1.code)[0]; - if (!relevantError) return; - if (info.positionNode.kind !== ts.SyntaxKind.Identifier) return; - - // TODO: use type checker to see if item of `.` before hand is a class - // But for now just run with it. - - var match = getIdentifierAndClassNames(relevantError); - - if (!match) return; - - var {identifierName, className} = match; - return { display: `Add ${identifierName} to ${className}` }; - } - - provideFix(info: QuickFixQueryInformation): Refactoring[] { - var relevantError = info.positionErrors.filter(x=> x.code == ts.Diagnostics.Property_0_does_not_exist_on_type_1.code)[0]; - var identifier = info.positionNode; - - var identifierName = identifier.text; - var {className} = getIdentifierAndClassNames(relevantError); - - // Get the type of the stuff on the right if its an assignment - var typeString = 'any'; - var parentOfParent = identifier.parent.parent; - if (parentOfParent.kind == ts.SyntaxKind.BinaryExpression - && (parentOfParent).operatorToken.getText().trim() == '=') { - - let binaryExpression = parentOfParent; - typeString = getTypeStringForNode(binaryExpression.right, info.typeChecker); - } - else if (parentOfParent.kind == ts.SyntaxKind.CallExpression) { - let callExp = parentOfParent; - let typeStringParts = ['(']; - - // Find the number of arguments - let args = []; - callExp.arguments.forEach(arg => { - var argName = (getLastNameAfterDot(arg.getText())); - var argType = getTypeStringForNode(arg, info.typeChecker); - - args.push(`${argName}: ${argType}`); - }); - typeStringParts.push(args.join(', ')); - - // TODO: infer the return type as well if the next parent is an assignment - // Currently its `any` - typeStringParts.push(') => any'); - typeString = typeStringParts.join(''); - } - - // Find the containing class declaration - var memberTarget = ast.getNodeByKindAndName(info.program, ts.SyntaxKind.ClassDeclaration, className); - if (!memberTarget) { - // Find the containing interface declaration - memberTarget = ast.getNodeByKindAndName(info.program, ts.SyntaxKind.InterfaceDeclaration, className); - } - if (!memberTarget) { - return []; - } - - // The following code will be same (and typesafe) for either class or interface - let targetDeclaration = memberTarget; - - // Then the first brace - let firstBrace = targetDeclaration.getChildren().filter(x=> x.kind == ts.SyntaxKind.OpenBraceToken)[0]; - - // And the correct indent - var indentLength = info.service.getIndentationAtPosition( - memberTarget.getSourceFile().fileName, firstBrace.end, info.project.projectFile.project.formatCodeOptions); - var indent = Array(indentLength + info.project.projectFile.project.formatCodeOptions.IndentSize + 1).join(' '); - - // And add stuff after the first brace - let refactoring: Refactoring = { - span: { - start: firstBrace.end, - length: 0 - }, - newText: `${EOL}${indent}${identifierName}: ${typeString};`, - filePath: targetDeclaration.getSourceFile().fileName - }; - - return [refactoring]; - } -} \ No newline at end of file diff --git a/lib/main/lang/fixmyts/quickFixes/addClassMethod.ts b/lib/main/lang/fixmyts/quickFixes/addClassMethod.ts deleted file mode 100644 index 108432eef..000000000 --- a/lib/main/lang/fixmyts/quickFixes/addClassMethod.ts +++ /dev/null @@ -1,252 +0,0 @@ -import {QuickFix, QuickFixQueryInformation, Refactoring, CanProvideFixResponse} from "../quickFix"; -import * as ast from "../astUtils"; -import {EOL} from "os"; - -function getIdentifierAndClassNames(error: ts.Diagnostic) { - var errorText: string = error.messageText; - if (typeof errorText !== 'string') { - console.error('I have no idea what this is:', errorText); - return undefined; - }; - - // see https://github.com/Microsoft/TypeScript/blob/6637f49209ceb5ed719573998381eab010fa48c9/src/compiler/diagnosticMessages.json#L842 - var match = errorText.match(/Property \'(\w+)\' does not exist on type \'(\w+)\'./); - - // Happens when the type name is an alias. We can't refactor in this case anyways - if (!match) return; - - var [, identifierName, className] = match; - return { identifierName, className }; -} - -/** foo.a => a */ -function getLastNameAfterDot(text: string) { - return text.substr(text.lastIndexOf('.') + 1); -} - -function getTypeStringForNode(node: ts.Node, typeChecker: ts.TypeChecker) { - var type = typeChecker.getTypeAtLocation(node); - - /** Discoverd from review of `services.getQuickInfoAtPosition` */ - return ts.displayPartsToString(ts.typeToDisplayParts(typeChecker, type)).replace(/\s+/g, ' '); -} - -export class AddClassMethod implements QuickFix { - key = AddClassMethod.name; - - canProvideFix(info: QuickFixQueryInformation): CanProvideFixResponse { - var relevantError = info.positionErrors.filter(x=> x.code == ts.Diagnostics.Property_0_does_not_exist_on_type_1.code)[0]; - if (!relevantError) return; - if (info.positionNode.kind !== ts.SyntaxKind.Identifier) return; - - // TODO: use type checker to see if item of `.` before hand is a class - // But for now just run with it. - - var match = getIdentifierAndClassNames(relevantError); - - if (!match) return; - - var {identifierName, className} = match; - return { display: `Add method "${identifierName}" to current class ${className}` }; - } - - provideFix(info: QuickFixQueryInformation): Refactoring[] { - var relevantError = info.positionErrors.filter(x=> x.code == ts.Diagnostics.Property_0_does_not_exist_on_type_1.code)[0]; - var identifier = info.positionNode; - - var identifierName = identifier.text; - var {className} = getIdentifierAndClassNames(relevantError); - - // Get the type of the stuff on the right if its an assignment - var typeString = 'any'; - var parentOfParent = identifier.parent.parent; - if (parentOfParent.kind == ts.SyntaxKind.BinaryExpression - && (parentOfParent).operatorToken.getText().trim() == '=') { - - let binaryExpression = parentOfParent; - typeString = getTypeStringForNode(binaryExpression.right, info.typeChecker); - - } - else if (parentOfParent.kind == ts.SyntaxKind.CallExpression) { - - let nativeTypes = ['string', 'number', 'boolean', 'object', 'null', 'undefined', 'RegExp']; - let abc = 'abcdefghijklmnopqrstuvwxyz'; - let argsAlphabet = abc.split(''); - let argsAlphabetPosition = 0; - let argName = ''; - let argCount = 0; - - let callExp = parentOfParent; - let typeStringParts = ['(']; - - // Find the number of arguments - let args = []; - callExp.arguments.forEach(arg => { - var argType = getTypeStringForNode(arg, info.typeChecker); - - // determine argument output type - // use consecutive letters for native types - // or use decapitalized Class name + counter as argument name - if (nativeTypes.indexOf(argType) != -1 //native types - || argType.indexOf('{') != -1 //Casted inline argument declarations - || argType.indexOf('=>') != -1 //Method references - || argType.indexOf('[]') != -1 //Array references - ) { - - var type:ts.Type = info.typeChecker.getTypeAtLocation(arg); - var typeName:string = "type"; - if (type && - type.symbol && - type.symbol.name) { - typeName = type.symbol.name.replace(/[\[\]]/g,''); - }; - var hasAnonymous = typeName.indexOf('__') == 0; - var isAnonymousTypedArgument = hasAnonymous && typeName.substring(2) == "type"; - var isAnonymousMethod = hasAnonymous && typeName.substring(2) == "function"; - var isAnonymousObject = hasAnonymous && typeName.substring(2) == "object"; - - if (argType.indexOf('=>') != -1 && - !isAnonymousTypedArgument && - !isAnonymousMethod && - !isAnonymousObject) { - if( typeName =='Array' ) typeName = 'array'; - argName = `${typeName}${argCount++}`; - } - else if( argType.indexOf('[]') != -1 ) - { - argName = `array${argCount++}`; - } - else { - if (isAnonymousMethod) { - typeName = "function"; - argName = `${typeName}${argCount++}`; - } - else if (isAnonymousObject) { - typeName = "object"; - argName = `${typeName}${argCount++}`; - } - else { - argName = argsAlphabet[argsAlphabetPosition]; - argsAlphabet[argsAlphabetPosition] += argsAlphabet[argsAlphabetPosition].substring(1); - argsAlphabetPosition++; - argsAlphabetPosition %= abc.length; - } - } - } - else { - // replace 'typeof ' from name - argName = argType.replace('typeof ', ''); - // decapitalize and concat - if (argType.indexOf('typeof ') == -1) { - var firstLower = argName[0].toLowerCase(); - - if (argName.length == 1) { - argName = firstLower; - } - else { - argName = firstLower + argName.substring(1); - } - } - // add counter value and increment it - argName += argCount.toString(); - argCount++ - } - - // cast null and undefined to any type - if (argType.indexOf('null')!=-1 || argType.indexOf('undefined')!=-1) { - argType = argType.replace(/null|undefined/g,'any'); - } - args.push(`${argName}: ${argType}`); - - }); - typeStringParts.push(args.join(', ')); - - // TODO: infer the return type as well if the next parent is an assignment - // Currently its `any` - typeStringParts.push(`): any { }`); - typeString = typeStringParts.join(''); - } - - // Find the containing class declaration - var memberTarget = ast.getNodeByKindAndName(info.program, ts.SyntaxKind.ClassDeclaration, className); - if (!memberTarget) { - // Find the containing interface declaration - memberTarget = ast.getNodeByKindAndName(info.program, ts.SyntaxKind.InterfaceDeclaration, className); - } - if (!memberTarget) { - return []; - } - - // The following code will be same (and typesafe) for either class or interface - let targetDeclaration = memberTarget; - - // Then the first brace - let firstBrace = targetDeclaration.getChildren().filter(x=> x.kind == ts.SyntaxKind.OpenBraceToken)[0]; - - // And the correct indent - var indentLength = info.service.getIndentationAtPosition( - memberTarget.getSourceFile().fileName, firstBrace.end, info.project.projectFile.project.formatCodeOptions); - var indent = Array(indentLength + info.project.projectFile.project.formatCodeOptions.IndentSize + 1).join(' '); - - // And add stuff after the first brace - let refactoring: Refactoring = { - span: { - start: firstBrace.end, - length: 0 - }, - newText: `${EOL}${indent}public ${identifierName}${typeString}`, - filePath: targetDeclaration.getSourceFile().fileName - }; - - return [refactoring]; - } -} - - - -/* TESTS */ -/* -enum EnumTest{ - one,two -} -class DataClass{}; -class FixTests{ - - public static STATIC_METHOD():typeof FixTests{ return FixTests } - public instanceMethod():FixTests{ return this;} - public instanceGeneric(a:T):T{ return a;} - constructor(){ - this.simple(true,1,'1',/1/g,null,undefined); - this.methods( this.instanceMethod, FixTests.STATIC_METHOD ); - this.enums( EnumTest, EnumTest.one ); - this.castedMembers( - {}, - <{x:number; y:number}>{}, - <{fn:(e:FixTests)=>FixTests}>{} - ); - this.inlineMethods(():number=>{ return -1;}); - this.inlineObjects({ - quickFix:new FixTests, - type:FixTests, - step:EnumTest.two - }); - this.genericMethod( this.instanceGeneric, this.instanceGeneric(this) ); - - this.arraySimple([true], [1], ['1'], [/1/g],[null],[undefined]); - this.arrayMethods([this.instanceMethod, FixTests.STATIC_METHOD]); - this.arrayEnums([EnumTest], [EnumTest.one]); - this.arrayCastedMembers( - [{}], - [<{ x: number; y: number }>{}], - [<{ fn: (e: FixTests) => FixTests }>{}] - ); - this.arrayInlineMethods([(): number=> { return -1; }]); - this.arrayInlineObjects([{ - quickFix: new FixTests, - type: FixTests, - step: EnumTest.two - }]); - this.arrayGenericMethod([this.instanceGeneric], [this.instanceGeneric(this)]); - } -} -*/ diff --git a/lib/main/lang/fixmyts/quickFixes/addImportDefaultStatement.ts b/lib/main/lang/fixmyts/quickFixes/addImportDefaultStatement.ts deleted file mode 100644 index ebcb64436..000000000 --- a/lib/main/lang/fixmyts/quickFixes/addImportDefaultStatement.ts +++ /dev/null @@ -1,82 +0,0 @@ -import {QuickFix, QuickFixQueryInformation, Refactoring, CanProvideFixResponse} from "../quickFix"; -import * as ast from "../astUtils"; -import {EOL } from "os"; -var { displayPartsToString, typeToDisplayParts } = ts; -import path = require('path'); -import {Project} from "../../core/project"; - -import {getPathCompletions} from "../../modules/getPathCompletions"; - -function getIdentifierAndFileNames(error: ts.Diagnostic, project: Project) { - - var errorText: string = error.messageText; - - // We don't support error chains yet - if (typeof errorText !== 'string') { - return undefined; - }; - - var match = errorText.match(/Cannot find name \'(\w+)\'./); - - // If for whatever reason the error message doesn't match - if (!match) return; - - var [, identifierName] = match; - var {files} = getPathCompletions({ - project, - filePath: error.file.fileName, - prefix: identifierName, - includeExternalModules: false - }); - var file = files.length > 0 ? files[0].relativePath : undefined; - var basename = files.length > 0 ? files[0].name : undefined; - return { identifierName, file, basename }; -} - -export class AddImportDefaultStatement implements QuickFix { - key = AddImportDefaultStatement.name; - - canProvideFix(info: QuickFixQueryInformation): CanProvideFixResponse { - var relevantError = info.positionErrors.filter(x => x.code == 2304)[0]; - if (!relevantError) return; - if (info.positionNode.kind !== ts.SyntaxKind.Identifier) return; - var matches = getIdentifierAndFileNames(relevantError, info.project); - if (!matches) return; - var { identifierName, file} = matches; - return file ? { display: `import ${identifierName} from \"${file}\"` } : undefined; - } - - provideFix(info: QuickFixQueryInformation): Refactoring[] { - var relevantError = info.positionErrors.filter(x => x.code == 2304)[0]; - var identifier = info.positionNode; - - var identifierName = identifier.text; - var fileNameforFix = getIdentifierAndFileNames(relevantError, info.project); - // Add stuff at the top of the file - let refactorings: Refactoring[] = [{ - span: { - start: 0, - length: 0 - }, - newText: `import ${identifierName} from \"${fileNameforFix.file}\";${EOL}`, - filePath: info.sourceFile.fileName - }]; - - // Also refactor the variable name to match the file name - // TODO: the following code only takes into account location - // There may be other locations where this is used. - // Better that they trigger a *rename* explicitly later if they want to rename the variable - // if (identifierName !== fileNameforFix.basename) { - // refactorings.push({ - // span: { - // start: identifier.getStart(), - // length: identifier.end - identifier.getStart() - // }, - // newText: fileNameforFix.basename, - // filePath: info.srcFile.fileName - // }) - // } - - return refactorings; - } -} diff --git a/lib/main/lang/fixmyts/quickFixes/addImportFromStatement.ts b/lib/main/lang/fixmyts/quickFixes/addImportFromStatement.ts deleted file mode 100644 index b16d9758a..000000000 --- a/lib/main/lang/fixmyts/quickFixes/addImportFromStatement.ts +++ /dev/null @@ -1,82 +0,0 @@ -import {QuickFix, QuickFixQueryInformation, Refactoring, CanProvideFixResponse} from "../quickFix"; -import * as ast from "../astUtils"; -import {EOL } from "os"; -var { displayPartsToString, typeToDisplayParts } = ts; -import path = require('path'); -import {Project} from "../../core/project"; - -import {getPathCompletions} from "../../modules/getPathCompletions"; - -function getIdentifierAndFileNames(error: ts.Diagnostic, project: Project) { - - var errorText: string = error.messageText; - - // We don't support error chains yet - if (typeof errorText !== 'string') { - return undefined; - }; - - var match = errorText.match(/Cannot find name \'(\w+)\'./); - - // If for whatever reason the error message doesn't match - if (!match) return; - - var [, identifierName] = match; - var {files} = getPathCompletions({ - project, - filePath: error.file.fileName, - prefix: identifierName, - includeExternalModules: false - }); - var file = files.length > 0 ? files[0].relativePath : undefined; - var basename = files.length > 0 ? files[0].name : undefined; - return { identifierName, file, basename }; -} - -export class AddImportFromStatement implements QuickFix { - key = AddImportFromStatement.name; - - canProvideFix(info: QuickFixQueryInformation): CanProvideFixResponse { - var relevantError = info.positionErrors.filter(x => x.code == 2304)[0]; - if (!relevantError) return; - if (info.positionNode.kind !== ts.SyntaxKind.Identifier) return; - var matches = getIdentifierAndFileNames(relevantError, info.project); - if (!matches) return; - var { identifierName, file} = matches; - return file ? { display: `import {${identifierName}} from \"${file}\"` } : undefined; - } - - provideFix(info: QuickFixQueryInformation): Refactoring[] { - var relevantError = info.positionErrors.filter(x => x.code == 2304)[0]; - var identifier = info.positionNode; - - var identifierName = identifier.text; - var fileNameforFix = getIdentifierAndFileNames(relevantError, info.project); - // Add stuff at the top of the file - let refactorings: Refactoring[] = [{ - span: { - start: 0, - length: 0 - }, - newText: `import {${identifierName}} from \"${fileNameforFix.file}\";${EOL}`, - filePath: info.sourceFile.fileName - }]; - - // Also refactor the variable name to match the file name - // TODO: the following code only takes into account location - // There may be other locations where this is used. - // Better that they trigger a *rename* explicitly later if they want to rename the variable - // if (identifierName !== fileNameforFix.basename) { - // refactorings.push({ - // span: { - // start: identifier.getStart(), - // length: identifier.end - identifier.getStart() - // }, - // newText: fileNameforFix.basename, - // filePath: info.srcFile.fileName - // }) - // } - - return refactorings; - } -} diff --git a/lib/main/lang/fixmyts/quickFixes/addImportStatement.ts b/lib/main/lang/fixmyts/quickFixes/addImportStatement.ts deleted file mode 100644 index 32458bede..000000000 --- a/lib/main/lang/fixmyts/quickFixes/addImportStatement.ts +++ /dev/null @@ -1,84 +0,0 @@ -import {QuickFix, QuickFixQueryInformation, Refactoring, CanProvideFixResponse} from "../quickFix"; -import * as ast from "../astUtils"; -import {EOL } from "os"; -var { displayPartsToString, typeToDisplayParts } = ts; -import path = require('path'); -import {Project} from "../../core/project"; - -import {getPathCompletions} from "../../modules/getPathCompletions"; - -function getIdentifierAndFileNames(error: ts.Diagnostic, project: Project) { - - var errorText: string = error.messageText; - - // We don't support error chains yet - if (typeof errorText !== 'string') { - return undefined; - }; - - var match = errorText.match(/Cannot find name \'(\w+)\'./); - - // If for whatever reason the error message doesn't match - if (!match) return; - - var [, identifierName] = match; - var {files} = getPathCompletions({ - project, - filePath: error.file.fileName, - prefix: identifierName, - includeExternalModules: false - }); - var file = files.length > 0 ? files[0].relativePath : undefined; - var basename = files.length > 0 ? files[0].name : undefined; - return { identifierName, file, basename }; -} - -export class AddImportStatement implements QuickFix { - key = AddImportStatement.name; - - canProvideFix(info: QuickFixQueryInformation): CanProvideFixResponse { - var relevantError = info.positionErrors.filter(x => x.code == 2304)[0]; - if (!relevantError) return; - if (info.positionNode.kind !== ts.SyntaxKind.Identifier) return; - var matches = getIdentifierAndFileNames(relevantError, info.project); - if (!matches) return; - - var { identifierName, file} = matches; - return file ? { display: `import ${identifierName} = require(\"${file}\")` } : undefined; - } - - provideFix(info: QuickFixQueryInformation): Refactoring[] { - var relevantError = info.positionErrors.filter(x => x.code == 2304)[0]; - var identifier = info.positionNode; - - var identifierName = identifier.text; - var fileNameforFix = getIdentifierAndFileNames(relevantError, info.project); - - // Add stuff at the top of the file - let refactorings: Refactoring[] = [{ - span: { - start: 0, - length: 0 - }, - newText: `import ${identifierName} = require(\"${fileNameforFix.file}\");${EOL}`, - filePath: info.sourceFile.fileName - }]; - - // Also refactor the variable name to match the file name - // TODO: the following code only takes into account location - // There may be other locations where this is used. - // Better that they trigger a *rename* explicitly later if they want to rename the variable - // if (identifierName !== fileNameforFix.basename) { - // refactorings.push({ - // span: { - // start: identifier.getStart(), - // length: identifier.end - identifier.getStart() - // }, - // newText: fileNameforFix.basename, - // filePath: info.srcFile.fileName - // }) - // } - - return refactorings; - } -} diff --git a/lib/main/lang/fixmyts/quickFixes/equalsToEquals.ts b/lib/main/lang/fixmyts/quickFixes/equalsToEquals.ts deleted file mode 100644 index f0ffa73a2..000000000 --- a/lib/main/lang/fixmyts/quickFixes/equalsToEquals.ts +++ /dev/null @@ -1,38 +0,0 @@ -import {QuickFix, QuickFixQueryInformation, Refactoring, CanProvideFixResponse} from "../quickFix"; -import * as ast from "../astUtils"; -import {EOL} from "os"; - -export class EqualsToEquals implements QuickFix { - key = EqualsToEquals.name; - - canProvideFix(info: QuickFixQueryInformation): CanProvideFixResponse { - if (info.positionNode.kind === ts.SyntaxKind.EqualsEqualsToken) { - return { display: "Convert == to ===" }; - } - if (info.positionNode.kind === ts.SyntaxKind.ExclamationEqualsToken) { - return { display: "Convert != to !==" }; - } - } - - provideFix(info: QuickFixQueryInformation): Refactoring[] { - - if (info.positionNode.kind === ts.SyntaxKind.EqualsEqualsToken) { - var newText = '==='; - } - if (info.positionNode.kind === ts.SyntaxKind.ExclamationEqualsToken) { - var newText = '!=='; - } - - var refactoring: Refactoring = { - span: { - // Since TypeScript stores trivia at with the node `pos` we only want 2 steps behind the `end` instead of `pos` - start: info.positionNode.end - 2, - length: 2 - }, - newText, - filePath: info.filePath - }; - - return [refactoring]; - } -} diff --git a/lib/main/lang/fixmyts/quickFixes/extractVariable.ts b/lib/main/lang/fixmyts/quickFixes/extractVariable.ts deleted file mode 100644 index 7d473d411..000000000 --- a/lib/main/lang/fixmyts/quickFixes/extractVariable.ts +++ /dev/null @@ -1,218 +0,0 @@ -import {QuickFix, QuickFixQueryInformation, Refactoring, CanProvideFixResponse} from "../quickFix"; -import * as ast from "../astUtils"; -import {EOL} from "os"; - -export class ExtractVariable implements QuickFix { - key = ExtractVariable.name; - - canProvideFix(info: QuickFixQueryInformation): CanProvideFixResponse { - - return execute(info, - () => { - let identifier = info.positionNode; - return { display: `Extract variable from ${identifier.text}` }; - }, - () => { - let identifier = info.positionNode; - return { display: `Extract variable from ${identifier.text}` }; - }, - () => { - return { display: `Extract variable` }; - }); - } - - provideFix(info: QuickFixQueryInformation): Refactoring[] { - - return execute(info, - () => { - return extractVariableFromCall(info); - }, - () => { - return extractVariableFromCall(info, "Result"); - }, - (callExpression) => { - return extractVariableFromArg(info, callExpression); - }); - } - -} - -function execute(info: QuickFixQueryInformation, onProperty, onFuncCall, onExtractable) { - - let callExpression = findLowestNode( - info.positionNode, - ts.SyntaxKind.CallExpression); - - if (callExpression) { - if (isPropertyCall(info)) { - return onProperty(); - } else if (isFuncCall(info)) { - return onFuncCall(); - } else if (isExtractable(info, callExpression)) { - return onExtractable(callExpression); - } - } else if (isPropertyAccess(info)) { - return onProperty(); - } - -} - -function extractVariableFromCall(info: QuickFixQueryInformation, postFix: string = ''): Refactoring[] { - - let typeChecker = info.typeChecker; - let type = getTypeStringForNode(info.positionNode, typeChecker); - let identifier = info.positionNode; - - return [{ - span: { - start: startOfLine(info) + indentAtPos(info), - length: 0 - }, - newText: `var ${identifier.text}${postFix}: ${type} = `, - filePath: info.filePath - }]; - -} - -function extractVariableFromArg(info: QuickFixQueryInformation, callExpression: ts.CallExpression): Refactoring[] { - - let argumentIndex = getArgumentIndex(info.positionNode, callExpression); - let {name, type} = getArgumentDescription(callExpression, - argumentIndex, info.typeChecker); - - let indent = indentAtPos(info); - let value = extractValue(info, callExpression); - - return [ - { - span: { - start: callExpression.arguments[argumentIndex].getStart(), - length: value.length - }, - newText: name, - filePath: info.filePath - }, - { - span: { - start: startOfLine(info) + indent, - length: 0 - }, - newText: `var ${name}: ${type} = ${value};${EOL}${createIndent(indent) }`, - filePath: info.filePath - }]; - -} - -function isPropertyAccess(info: QuickFixQueryInformation): boolean { - return isValidPath(info.positionNode, - [ts.SyntaxKind.Identifier, - ts.SyntaxKind.PropertyAccessExpression, - ts.SyntaxKind.ExpressionStatement]); -} - -function isFuncCall(info: QuickFixQueryInformation): boolean { - return isValidPath(info.positionNode, - [ts.SyntaxKind.Identifier, - ts.SyntaxKind.CallExpression, - ts.SyntaxKind.ExpressionStatement]); -} - -function isPropertyCall(info: QuickFixQueryInformation): boolean { - return isValidPath(info.positionNode, - [ts.SyntaxKind.Identifier, - ts.SyntaxKind.PropertyAccessExpression, - ts.SyntaxKind.CallExpression, - ts.SyntaxKind.ExpressionStatement]); -} - -function isExtractable(info: QuickFixQueryInformation, callExpression: ts.CallExpression): boolean { - let argumentIndex = getArgumentIndex(info.positionNode, callExpression); - return (argumentIndex > -1) && - (!((info.positionNode.kind == ts.SyntaxKind.Identifier) && - (info.positionNode.parent == callExpression))); -} - -function findLowestNode(startNode: ts.Node, kind: ts.SyntaxKind): T { - let node = startNode; - let result = new Array(); - while (node) { - if (node.kind == kind) { - result.push(node); - } - node = node.parent; - } - if (result.length == 0) { - return null; - } else { - return result.reverse()[0]; - } -} - -function getArgumentDescription(node: ts.CallExpression, argumentIndex: number, - typeChecker: ts.TypeChecker) { - - let signature = typeChecker.getResolvedSignature(node); - let argument = signature.parameters[argumentIndex]; - let sigDeclaration = (argument.valueDeclaration).type; - - return { - name: argument.name.trim(), - type: node.getSourceFile().text.substring(sigDeclaration.pos, sigDeclaration.end).trim() - } -} - -function startOfLine(info: QuickFixQueryInformation): number { - let {line} = info.project.languageServiceHost.getPositionFromIndex(info.filePath, info.position); - return info.project.languageServiceHost.getIndexFromPosition(info.filePath, { line, col: 0 }); -} - -function indentAtPos(info: QuickFixQueryInformation): number { - return info.service.getIndentationAtPosition( - info.filePath, info.positionNode.pos, info.project.projectFile.project.formatCodeOptions); -} - -function createIndent(indent: number): string { - return Array(indent + 1).join(' '); -} - -function getTypeStringForNode(node: ts.Node, typeChecker: ts.TypeChecker): string { - let type = typeChecker.getTypeAtLocation(node); - let typeSignature = ts.displayPartsToString(ts.typeToDisplayParts(typeChecker, type)).replace(/\s+/g, ' '); - let fatArrowPos = typeSignature.indexOf("=>"); - - if (fatArrowPos != -1) { - return typeSignature.substr(fatArrowPos + 3).trim(); - } else { - return typeSignature.trim(); - } -} - -function extractValue(info: QuickFixQueryInformation, callExpression: ts.CallExpression): string { - let index = getArgumentIndex(info.positionNode, callExpression); - let argNode = callExpression.arguments[index]; - return info.positionNode.getSourceFile().text.substr(argNode.pos, argNode.end - argNode.pos).trim(); -} - -function getArgumentIndex(node: ts.Node, callExpression: ts.CallExpression): number { - for (let i = 0; i < callExpression.arguments.length; i++) { - let arg = callExpression.arguments[i]; - if ((node.pos >= arg.pos) && (node.end <= arg.end)) { - return i; - } - } - return -1; -} - -function isValidPath(startNode: ts.Node, kinds: Array): boolean { - var node = startNode; - for (let i = 0; i < kinds.length; i++) { - if (!(node.kind == kinds[i])) { - return false; - } - node = node.parent; - if (!node) { - return false; - } - } - return true; -} diff --git a/lib/main/lang/fixmyts/quickFixes/implementInterface.ts b/lib/main/lang/fixmyts/quickFixes/implementInterface.ts deleted file mode 100644 index ed32be141..000000000 --- a/lib/main/lang/fixmyts/quickFixes/implementInterface.ts +++ /dev/null @@ -1,75 +0,0 @@ -import {QuickFix, QuickFixQueryInformation, Refactoring, CanProvideFixResponse} from "../quickFix"; -import * as ast from "../astUtils"; -import {EOL} from "os"; - -function getClassAndInterfaceName(error: ts.Diagnostic) { - var errorText: string = ts.flattenDiagnosticMessageText(error.messageText, EOL); - - var match = errorText.match(/Class \'(\w+)\' incorrectly implements interface \'(\w+)\'./); - - // safety - if (!match || match.length !== 3) return; - - var [, className, interfaceName] = match; - return { className, interfaceName }; -} - -export class ImplementInterface implements QuickFix { - key = ImplementInterface.name; - - canProvideFix(info: QuickFixQueryInformation): CanProvideFixResponse { - var relevantError = info.positionErrors.filter(x=> x.code == ts.Diagnostics.Class_0_incorrectly_implements_interface_1.code)[0]; - if (!relevantError) return; - if (info.positionNode.kind !== ts.SyntaxKind.Identifier) return; - - var match = getClassAndInterfaceName(relevantError); - - if (!match) return; - - var {className, interfaceName} = match; - return { display: `Implement members of ${interfaceName} in ${className}` }; - } - - provideFix(info: QuickFixQueryInformation): Refactoring[] { - var relevantError = info.positionErrors.filter(x=> x.code == ts.Diagnostics.Class_0_incorrectly_implements_interface_1.code)[0]; - if (!relevantError) return; - if (info.positionNode.kind !== ts.SyntaxKind.Identifier) return; - - var match = getClassAndInterfaceName(relevantError); - var {className, interfaceName} = match; - - // Get all the members of the interface: - let interfaceTarget = ast.getNodeByKindAndName(info.program, ts.SyntaxKind.InterfaceDeclaration, className); - - // The class that we are trying to add stuff to - let classTarget = ast.getNodeByKindAndName(info.program, ts.SyntaxKind.ClassDeclaration, className); - - // Then the last brace - let braces = classTarget.getChildren().filter(x=> x.kind == ts.SyntaxKind.CloseBraceToken); - let lastBrace = braces[braces.length - 1]; - - // And the correct indent - var indentLength = info.service.getIndentationAtPosition( - classTarget.getSourceFile().fileName, lastBrace.getStart(), info.project.projectFile.project.formatCodeOptions); - var indent = Array(indentLength + info.project.projectFile.project.formatCodeOptions.IndentSize + 1).join(' '); - - let refactorings: Refactoring[] = []; - - // - // The code for the error is actually from typeChecker.checkTypeRelatedTo so investigate that code more - // also look at the code from the mixin PR on ms/typescript - // - - // And add stuff after the last brace - // let refactoring: Refactoring = { - // span: { - // start: firstBrace.end, - // length: 0 - // }, - // newText: `${EOL}${indent}${identifierName}: ${typeString};`, - // filePath: targetDeclaration.getSourceFile().fileName - // }; - - return refactorings; - } -} \ No newline at end of file diff --git a/lib/main/lang/fixmyts/quickFixes/quoteToTemplate.ts b/lib/main/lang/fixmyts/quickFixes/quoteToTemplate.ts deleted file mode 100644 index 57d1ed7d4..000000000 --- a/lib/main/lang/fixmyts/quickFixes/quoteToTemplate.ts +++ /dev/null @@ -1,43 +0,0 @@ -import {QuickFix, QuickFixQueryInformation, Refactoring, CanProvideFixResponse} from "../quickFix"; -import * as ast from "../astUtils"; -import {EOL} from "os"; - -export class QuoteToTemplate implements QuickFix { - key = QuoteToTemplate.name; - - canProvideFix(info: QuickFixQueryInformation): CanProvideFixResponse { - if (info.positionNode.kind === ts.SyntaxKind.StringLiteral) { - return { display: `Convert to Template String` }; - } - } - - provideFix(info: QuickFixQueryInformation): Refactoring[] { - - var text = info.positionNode.getText(); - var quoteCharacter = text.trim()[0]; - var nextQuoteCharacter = '`'; - - // The following code is same as `quotesToQuotes. Refactor!` - - var quoteRegex = new RegExp(quoteCharacter, 'g') - var escapedQuoteRegex = new RegExp(`\\\\${quoteCharacter}`, 'g') - var nextQuoteRegex = new RegExp(nextQuoteCharacter, 'g') - - var newText = text - .replace(nextQuoteRegex, `\\${nextQuoteCharacter}`) - .replace(escapedQuoteRegex, quoteCharacter); - - newText = nextQuoteCharacter + newText.substr(1, newText.length - 2) + nextQuoteCharacter - - var refactoring: Refactoring = { - span: { - start: info.positionNode.getStart(), - length: info.positionNode.end - info.positionNode.getStart() - }, - newText, - filePath: info.filePath - }; - - return [refactoring]; - } -} diff --git a/lib/main/lang/fixmyts/quickFixes/quotesToQuotes.ts b/lib/main/lang/fixmyts/quickFixes/quotesToQuotes.ts deleted file mode 100644 index f86f46c33..000000000 --- a/lib/main/lang/fixmyts/quickFixes/quotesToQuotes.ts +++ /dev/null @@ -1,47 +0,0 @@ -import {QuickFix, QuickFixQueryInformation, Refactoring, CanProvideFixResponse} from "../quickFix"; -import * as ast from "../astUtils"; -import {EOL} from "os"; - -export class QuotesToQuotes implements QuickFix { - key = QuotesToQuotes.name; - - canProvideFix(info: QuickFixQueryInformation): CanProvideFixResponse { - if (info.positionNode.kind === ts.SyntaxKind.StringLiteral) { - if (info.positionNode.getText().trim()[0] === `'`) { - return { display: `Convert ' to "` }; - } - if (info.positionNode.getText().trim()[0] === `"`) { - return { display: `Convert " to '` }; - } - } - } - - provideFix(info: QuickFixQueryInformation): Refactoring[] { - - var text = info.positionNode.getText(); - var quoteCharacter = text.trim()[0]; - var nextQuoteCharacter = quoteCharacter === "'" ? '"' : "'"; - - // STOLEN : https://github.com/atom/toggle-quotes/blob/master/lib/toggle-quotes.coffee - var quoteRegex = new RegExp(quoteCharacter, 'g') - var escapedQuoteRegex = new RegExp(`\\\\${quoteCharacter}`, 'g') - var nextQuoteRegex = new RegExp(nextQuoteCharacter, 'g') - - var newText = text - .replace(nextQuoteRegex, `\\${nextQuoteCharacter}`) - .replace(escapedQuoteRegex, quoteCharacter); - - newText = nextQuoteCharacter + newText.substr(1, newText.length - 2) + nextQuoteCharacter - - var refactoring: Refactoring = { - span: { - start: info.positionNode.getStart(), - length: info.positionNode.end - info.positionNode.getStart() - }, - newText, - filePath: info.filePath - }; - - return [refactoring]; - } -} diff --git a/lib/main/lang/fixmyts/quickFixes/singleLineCommentToJsdoc.ts b/lib/main/lang/fixmyts/quickFixes/singleLineCommentToJsdoc.ts deleted file mode 100644 index 72b293072..000000000 --- a/lib/main/lang/fixmyts/quickFixes/singleLineCommentToJsdoc.ts +++ /dev/null @@ -1,50 +0,0 @@ -import utils = require("../../utils"); -import {QuickFix, QuickFixQueryInformation, Refactoring, CanProvideFixResponse} from "../quickFix"; -import * as ast from "../astUtils"; -import {EOL} from "os"; - -export class SingleLineCommentToJsdoc implements QuickFix { - key = SingleLineCommentToJsdoc.name; - - validNodes = utils.createMap([ - ts.SyntaxKind.ExportKeyword, - ts.SyntaxKind.VarKeyword, - ts.SyntaxKind.LetKeyword, - ts.SyntaxKind.ConstKeyword, - ts.SyntaxKind.FunctionKeyword, - ]); - - canProvideFix(info: QuickFixQueryInformation): CanProvideFixResponse { - if (this.validNodes[info.positionNode.kind]) { - let comments = ts.getLeadingCommentRangesOfNode(info.positionNode, info.sourceFile); - if (!comments) return; - - const mapped = comments.map(c=> info.sourceFileText.substring(c.pos, c.end)); - if (!mapped.length) return; - - let relevantComment = mapped[mapped.length - 1]; - - if (relevantComment.startsWith('//')) - return { display: 'Convert comment to jsDoc' }; - } - } - - provideFix(info: QuickFixQueryInformation): Refactoring[] { - - let comments = ts.getLeadingCommentRangesOfNode(info.positionNode, info.sourceFile); - let relevantComment = comments[comments.length - 1]; - var oldText = info.sourceFileText.substring(relevantComment.pos, relevantComment.end); - let newText = "/** " + oldText.substr(2).trim() + " */"; - - var refactoring: Refactoring = { - span: { - start: relevantComment.pos, - length: relevantComment.end - relevantComment.pos - }, - newText, - filePath: info.filePath - }; - - return [refactoring]; - } -} diff --git a/lib/main/lang/fixmyts/quickFixes/stringConcatToTemplate.ts b/lib/main/lang/fixmyts/quickFixes/stringConcatToTemplate.ts deleted file mode 100644 index 8e2cccaa4..000000000 --- a/lib/main/lang/fixmyts/quickFixes/stringConcatToTemplate.ts +++ /dev/null @@ -1,123 +0,0 @@ -import {QuickFix, QuickFixQueryInformation, Refactoring, CanProvideFixResponse} from "../quickFix"; -import * as ast from "../astUtils"; - -function isBinaryAddition(node: ts.Node): boolean { - return (node.kind == ts.SyntaxKind.BinaryExpression && - (node).operatorToken.kind == ts.SyntaxKind.PlusToken); -} - -function isStringExpression(node: ts.Node, typeChecker: ts.TypeChecker): boolean { - var type = typeChecker.getTypeAtLocation(node); - var flags = type.getFlags(); - return !!(flags & ts.TypeFlags.String); -} - -/** Returns the root (binary +) node if there is some otherwise returns undefined */ -function isAPartOfAChainOfStringAdditions(node: ts.Node, typeChecker: ts.TypeChecker): ts.BinaryExpression { - // We are looking for the `largestSumNode`. Its set once we find one up our tree - var largestSumNode: ts.BinaryExpression = undefined; - while (true) { - // Whenever we find a binary expression of type sum that evaluates to a string - if (isBinaryAddition(node) && isStringExpression(node, typeChecker)) { - largestSumNode = node; - } - - // We've gone too far up - if (node.kind == ts.SyntaxKind.SourceFile) { - return largestSumNode; - } - - // Next look at the parent to find a larger sum node - node = node.parent; - } -} - -export class StringConcatToTemplate implements QuickFix { - backTickCharacter = '`'; - backTick = new RegExp(this.backTickCharacter, 'g'); - $regex = /\$/g; - key = StringConcatToTemplate.name; - - canProvideFix(info: QuickFixQueryInformation): CanProvideFixResponse { - // Algo - // Can provide a quick fix if we are part of an expression that - // is a part of a binary + expression - // and when these binary +es end we come to an expression which is of type `string` - - // Based on algo we do not care about what the current thing is as long as its a part of a sum of additions - var strRoot = isAPartOfAChainOfStringAdditions(info.positionNode, info.typeChecker); - if (strRoot) { - return { display: 'String concatenations to a template string' }; - } - } - - provideFix(info: QuickFixQueryInformation): Refactoring[] { - const finalOutput: string[] = []; - - var strRoot = isAPartOfAChainOfStringAdditions(info.positionNode, info.typeChecker); - let current: ts.Node = strRoot; - - // We pop of each left node one by one - while (true) { - // if we are still in some sequence of additions - if (current.kind == ts.SyntaxKind.BinaryExpression) { - let binary = current; - this.appendToFinal(finalOutput, binary.right); - - // Continue with left - current = binary.left; - } - else { - this.appendToFinal(finalOutput, current); - break; - } - } - - let newText = this.backTickCharacter + - finalOutput.join('') + - this.backTickCharacter; - - var refactoring: Refactoring = { - span: { - start: strRoot.getStart(), - length: strRoot.end - strRoot.getStart() - }, - newText, - filePath: info.filePath - }; - - return [refactoring]; - } - - private appendToFinal(finalOutput: string[], node: ts.Node) { - // Each string literal needs : - // to be checked that it doesn't contain (`) and those need to be escaped. - // Also `$` needs escaping - // Also the quote characters at the limits need to be removed - if (node.kind == ts.SyntaxKind.StringLiteral) { - let text = node.getText(); - let quoteCharacter = text.trim()[0]; - - let quoteRegex = new RegExp(quoteCharacter, 'g') - let escapedQuoteRegex = new RegExp(`\\\\${quoteCharacter}`, 'g') - - let newText = text - .replace(this.backTick, `\\${this.backTickCharacter}`) - .replace(escapedQuoteRegex, quoteCharacter) - .replace(this.$regex, '\\$'); - - newText = newText.substr(1, newText.length - 2); - finalOutput.unshift(newText); - } - else if (node.kind == ts.SyntaxKind.TemplateExpression || node.kind == ts.SyntaxKind.NoSubstitutionTemplateLiteral) { - let text = node.getText(); - text = text.trim(); - text = text.substr(1, text.length - 2); - finalOutput.unshift(text); - } - // Each expression that isn't a string literal will just be escaped `${}` - else { - finalOutput.unshift('${' + node.getText() + '}'); - } - } -} diff --git a/lib/main/lang/fixmyts/quickFixes/typeAssertPropertyAccessToAny.ts b/lib/main/lang/fixmyts/quickFixes/typeAssertPropertyAccessToAny.ts deleted file mode 100644 index 185f9d126..000000000 --- a/lib/main/lang/fixmyts/quickFixes/typeAssertPropertyAccessToAny.ts +++ /dev/null @@ -1,58 +0,0 @@ -import {QuickFix, QuickFixQueryInformation, Refactoring, CanProvideFixResponse} from "../quickFix"; -import * as ast from "../astUtils"; - - -export class TypeAssertPropertyAccessToAny implements QuickFix { - key = TypeAssertPropertyAccessToAny.name; - - canProvideFix(info: QuickFixQueryInformation): CanProvideFixResponse { - var relevantError = info.positionErrors.filter(x=> x.code == ts.Diagnostics.Property_0_does_not_exist_on_type_1.code)[0]; - if (!relevantError) return; - if (info.positionNode.kind !== ts.SyntaxKind.Identifier) return; - - var match = getIdentifierName(info.positionErrorMessages[0]); - - if (!match) return; - - var {identifierName} = match; - return { display: `Assert "any" for property access "${identifierName}"` }; - } - - provideFix(info: QuickFixQueryInformation): Refactoring[] { - let parent = info.positionNode.parent; - if (parent.kind == ts.SyntaxKind.PropertyAccessExpression) { - let propertyAccess = parent; - - // Find the previous identifier skipping over the DotToken - let idx = propertyAccess.getChildren().indexOf(info.positionNode) - let prev = propertyAccess.getChildAt(idx-2); - - let start = propertyAccess.getStart(); - let end = prev.getEnd(); - - let oldText = propertyAccess.getText().substr(0, end - start); - - let refactoring: Refactoring = { - filePath: info.filePath, - span: { - start: start, - length: end - start, - }, - newText: `(${oldText} as any)` - }; - - return [refactoring]; - } - return []; - } -} - -function getIdentifierName(errorText: string) { - // see https://github.com/Microsoft/TypeScript/blob/6637f49209ceb5ed719573998381eab010fa48c9/src/compiler/diagnosticMessages.json#L842 - var match = /Property \'(\w+)\' does not exist on type \.*/.exec(errorText); - - if (!match) return; - - var [, identifierName] = match; - return { identifierName }; -} diff --git a/lib/main/lang/fixmyts/quickFixes/typeAssertPropertyAccessToType.ts b/lib/main/lang/fixmyts/quickFixes/typeAssertPropertyAccessToType.ts deleted file mode 100644 index 4318dcf9a..000000000 --- a/lib/main/lang/fixmyts/quickFixes/typeAssertPropertyAccessToType.ts +++ /dev/null @@ -1,59 +0,0 @@ -import {QuickFix, QuickFixQueryInformation, Refactoring, CanProvideFixResponse} from "../quickFix"; -import * as ast from "../astUtils"; - - -export class TypeAssertPropertyAccessToType implements QuickFix { - key = TypeAssertPropertyAccessToType.name; - - canProvideFix(info: QuickFixQueryInformation): CanProvideFixResponse { - var relevantError = info.positionErrors.filter(x=> x.code == ts.Diagnostics.Property_0_does_not_exist_on_type_1.code)[0]; - if (!relevantError) return; - if (info.positionNode.kind !== ts.SyntaxKind.Identifier) return; - - var match = getIdentifierName(info.positionErrorMessages[0]); - - if (!match) return; - - var {identifierName} = match; - return {display: `Assert for property access "${identifierName}"`, isNewTextSnippet: true}; - } - - provideFix(info: QuickFixQueryInformation): Refactoring[] { - let parent = info.positionNode.parent; - if (parent.kind == ts.SyntaxKind.PropertyAccessExpression) { - let propertyAccess = parent; - - // Find the previous identifier skipping over the DotToken - let idx = propertyAccess.getChildren().indexOf(info.positionNode) - let prev = propertyAccess.getChildAt(idx-2); - - let start = propertyAccess.getStart(); - let end = prev.getEnd(); - - let oldText = propertyAccess.getText().substr(0, end - start); - - let refactoring: Refactoring = { - filePath: info.filePath, - span: { - start: start, - length: propertyAccess.name.end - start, - }, - newText: `(${oldText} as \${1:any})\${2:.${propertyAccess.name.getText()}}\${3}`, - isNewTextSnippet: true, - }; - - return [refactoring]; - } - return []; - } -} - -function getIdentifierName(errorText: string) { - // see https://github.com/Microsoft/TypeScript/blob/6637f49209ceb5ed719573998381eab010fa48c9/src/compiler/diagnosticMessages.json#L842 - var match = /Property \'(\w+)\' does not exist on type \.*/.exec(errorText); - - if (!match) return; - - var [, identifierName] = match; - return { identifierName }; -} diff --git a/lib/main/lang/fixmyts/quickFixes/wrapInProperty.ts b/lib/main/lang/fixmyts/quickFixes/wrapInProperty.ts deleted file mode 100644 index a400f28cc..000000000 --- a/lib/main/lang/fixmyts/quickFixes/wrapInProperty.ts +++ /dev/null @@ -1,123 +0,0 @@ -import {QuickFix, QuickFixQueryInformation, Refactoring, CanProvideFixResponse} from "../quickFix"; -import * as ast from "../astUtils"; -import {EOL} from "os"; - -interface IndentSetting { - classIndent: number; - indent: number; -} - -export class WrapInProperty implements QuickFix { - key = WrapInProperty.name; - - canProvideFix(info: QuickFixQueryInformation): CanProvideFixResponse { - - if (info.positionNode && info.positionNode.parent && - info.positionNode.parent.parent && info.positionNode.parent.parent.symbol && - info.positionNode.parent.parent.symbol && info.positionNode.parent.parent.symbol.name == '__constructor') { - - if (info.positionNode.parent.kind == ts.SyntaxKind.Parameter) { - return { display: `Wrap ${info.positionNode.parent.symbol.name} in a read only property` }; - } - } - } - - provideFix(info: QuickFixQueryInformation): Refactoring[] { - let classDecl = info.positionNode.parent.parent.parent; - let constructorDecl = info.positionNode.parent.parent; - let paramDecl = info.positionNode.parent; - - let symbolName = info.positionNode.parent.symbol.name; - let typeName = getArgumentType(info, paramDecl); - - let firstBrace = classDecl.getChildren().filter(x=> x.kind == ts.SyntaxKind.OpenBraceToken)[0]; - - let classIndent = info.service.getIndentationAtPosition( - info.filePath, firstBrace.end, info.project.projectFile.project.formatCodeOptions); - let indent = info.project.projectFile.project.formatCodeOptions.IndentSize; - - let indentSetting = { - classIndent, - indent - }; - - let assignemnt = createAssignment( - constructorDecl, - symbolName, - indentSetting, - info.filePath); - - let property = createProperty( - classDecl, - symbolName, - typeName, - indentSetting, - info.filePath); - - return [assignemnt, property]; - - } -} - -function createAssignment( - constructorDecl: ts.ConstructorDeclaration, - symbolName: string, - indentSetting: IndentSetting, - filePath: string): Refactoring { - - let indentLevel2 = createIndent(indentSetting, 2); - let lastBrace = constructorDecl.body.getChildren() - .filter(x=> x.kind == ts.SyntaxKind.CloseBraceToken).reverse()[0]; - - let newText = `${EOL}${indentLevel2}this._${symbolName} = ${symbolName};`; - - return { - span: { - start: lastBrace.end - (6 + indentSetting.classIndent), - length: 0 - }, - newText: newText, - filePath: filePath - }; -} - -function createProperty( - classDecl: ts.ClassDeclaration, - symbolName: string, - typeName: string, - indentSetting: IndentSetting, - filePath: string): Refactoring { - - let indentLevel1 = createIndent(indentSetting, 1); - let indentLevel2 = createIndent(indentSetting, 2); - - let newText = `${EOL}${indentLevel1}_${symbolName}: ${typeName};` + - `${EOL}${indentLevel1}get ${symbolName}(): ${typeName} {`+ - `${EOL}${indentLevel2}return this._${symbolName};` + - `${EOL}${indentLevel1}}`; - - return { - span: { - start: classDecl.end - (2 + indentSetting.classIndent), - length: 0 - }, - newText: newText, - filePath: filePath - }; -} - -function createIndent(indentSetting: IndentSetting, level: number): string { - return Array(indentSetting.classIndent + (indentSetting.indent * level) + 1).join(' '); -} - -function getArgumentType( - info: QuickFixQueryInformation, - paramDecl: ts.ParameterDeclaration): string { - if (paramDecl.type) { - let start = paramDecl.type.pos; - let end = paramDecl.type.end; - return info.sourceFile.text.substr(start, (end - start)).trim(); - } else { - return 'any'; - } -} \ No newline at end of file diff --git a/lib/main/lang/modules/astToText.ts b/lib/main/lang/modules/astToText.ts deleted file mode 100644 index 2979cc1eb..000000000 --- a/lib/main/lang/modules/astToText.ts +++ /dev/null @@ -1,398 +0,0 @@ - -/** - * Things we care about: - * name , kind , text - */ -// Inspired by `ts.forEachChild`: -// https://github.com/Microsoft/TypeScript/blob/65cbd91667acf890f21a3527b3647c7bc994ca32/src/compiler/parser.ts#L43-L320 - -import {syntaxKindToString} from "../fixmyts/astUtils"; - -export function astToText(srcFile: ts.Node) { - - //// A useful function for debugging - // aggregate(srcFile, 0); - // function aggregate(node: ts.Node, depth: number): void { - // console.error(node.kind, (node.name && node.name.text), (node.parent), depth, node); - // ts.forEachChild(node, (node) => aggregate(node, depth + 1)); - // } - - var nodeIndex = 0; - function nodeToNodeDisplay(node: ts.Node, depth: number): NodeDisplay { - - var kind = syntaxKindToString(node.kind); - - var children = []; - ts.forEachChild(node, (cNode) => { - var child = nodeToNodeDisplay(cNode, depth + 1); - children.push(child); - }); - - var ret: NodeDisplay = { - kind, - children, - pos: node.pos, - end: node.end, - depth, - nodeIndex, - rawJson: prettyJSONNoParent(node) - }; - - // each time we get called index is incremented - nodeIndex++; - return ret; - } - - var root = nodeToNodeDisplay(srcFile, 0); - - return root; -} - -export function astToTextFull(srcFile: ts.Node) { - - //// A useful function for debugging - // aggregate(srcFile, 0); - // function aggregate(node: ts.Node, depth: number): void { - // console.error(node.kind, (node.name && node.name.text), (node.parent), depth, node); - // ts.forEachChild(node, (node) => aggregate(node, depth + 1)); - // } - - var nodeIndex = 0; - function nodeToNodeDisplay(node: ts.Node, depth: number): NodeDisplay { - - var kind = syntaxKindToString(node.kind); - - var children = []; - node.getChildren().forEach((cNode) => { - var child = nodeToNodeDisplay(cNode, depth + 1); - children.push(child); - }); - - var ret: NodeDisplay = { - kind, - children, - pos: node.pos, - end: node.end, - depth, - nodeIndex, - rawJson: prettyJSONNoParent(node) - }; - - // each time we get called index is incremented - nodeIndex++; - return ret; - } - - var root = nodeToNodeDisplay(srcFile, 0); - - return root; -} - -function prettyJSONNoParent(object: any): string { - var cache = []; - var value = JSON.stringify(object, - // fixup circular reference - function(key, value) { - if (key == 'parent'){ - return; - } - if (typeof value === 'object' && value !== null) { - if (cache.indexOf(value) !== -1) { - // Circular reference found, discard key - return; - } - // Store value in our collection - cache.push(value); - } - return value; - }, - // indent 4 spaces - 4); - cache = null; - return value; -} - -// import {Node,SyntaxKind,visitNode} from "typescript"; -// -// // Invokes a callback for each child of the given node. The 'cbNode' callback is invoked for all child nodes -// // stored in properties. If a 'cbNodes' callback is specified, it is invoked for embedded arrays; otherwise, -// // embedded arrays are flattened and the 'cbNode' callback is invoked for each element. If a callback returns -// // a truthy value, iteration stops and that value is returned. Otherwise, undefined is returned. -// export function forEachChild(node: Node, cbNode: (node: Node) => T, cbNodeArray?: (nodes: Node[]) => T): T { -// if (!node) { -// return; -// } -// // The visitXXX functions could be written as local functions that close over the cbNode and cbNodeArray -// // callback parameters, but that causes a closure allocation for each invocation with noticeable effects -// // on performance. -// let visitNodes: (cb: (node: Node | Node[]) => T, nodes: Node[]) => T = cbNodeArray ? visitNodeArray : visitEachNode; -// let cbNodes = cbNodeArray || cbNode; -// switch (node.kind) { -// case SyntaxKind.QualifiedName: -// return visitNode(cbNode, (node).left) || -// visitNode(cbNode, (node).right); -// case SyntaxKind.TypeParameter: -// return visitNode(cbNode, (node).name) || -// visitNode(cbNode, (node).constraint) || -// visitNode(cbNode, (node).expression); -// case SyntaxKind.Parameter: -// case SyntaxKind.PropertyDeclaration: -// case SyntaxKind.PropertySignature: -// case SyntaxKind.PropertyAssignment: -// case SyntaxKind.ShorthandPropertyAssignment: -// case SyntaxKind.VariableDeclaration: -// case SyntaxKind.BindingElement: -// return visitNodes(cbNodes, node.decorators) || -// visitNodes(cbNodes, node.modifiers) || -// visitNode(cbNode, (node).propertyName) || -// visitNode(cbNode, (node).dotDotDotToken) || -// visitNode(cbNode, (node).name) || -// visitNode(cbNode, (node).questionToken) || -// visitNode(cbNode, (node).type) || -// visitNode(cbNode, (node).initializer); -// case SyntaxKind.FunctionType: -// case SyntaxKind.ConstructorType: -// case SyntaxKind.CallSignature: -// case SyntaxKind.ConstructSignature: -// case SyntaxKind.IndexSignature: -// return visitNodes(cbNodes, node.decorators) || -// visitNodes(cbNodes, node.modifiers) || -// visitNodes(cbNodes, (node).typeParameters) || -// visitNodes(cbNodes, (node).parameters) || -// visitNode(cbNode, (node).type); -// case SyntaxKind.MethodDeclaration: -// case SyntaxKind.MethodSignature: -// case SyntaxKind.Constructor: -// case SyntaxKind.GetAccessor: -// case SyntaxKind.SetAccessor: -// case SyntaxKind.FunctionExpression: -// case SyntaxKind.FunctionDeclaration: -// case SyntaxKind.ArrowFunction: -// return visitNodes(cbNodes, node.decorators) || -// visitNodes(cbNodes, node.modifiers) || -// visitNode(cbNode, (node).asteriskToken) || -// visitNode(cbNode, (node).name) || -// visitNode(cbNode, (node).questionToken) || -// visitNodes(cbNodes, (node).typeParameters) || -// visitNodes(cbNodes, (node).parameters) || -// visitNode(cbNode, (node).type) || -// visitNode(cbNode, (node).equalsGreaterThanToken) || -// visitNode(cbNode, (node).body); -// case SyntaxKind.TypeReference: -// return visitNode(cbNode, (node).typeName) || -// visitNodes(cbNodes, (node).typeArguments); -// case SyntaxKind.TypeQuery: -// return visitNode(cbNode, (node).exprName); -// case SyntaxKind.TypeLiteral: -// return visitNodes(cbNodes, (node).members); -// case SyntaxKind.ArrayType: -// return visitNode(cbNode, (node).elementType); -// case SyntaxKind.TupleType: -// return visitNodes(cbNodes, (node).elementTypes); -// case SyntaxKind.UnionType: -// return visitNodes(cbNodes, (node).types); -// case SyntaxKind.ParenthesizedType: -// return visitNode(cbNode, (node).type); -// case SyntaxKind.ObjectBindingPattern: -// case SyntaxKind.ArrayBindingPattern: -// return visitNodes(cbNodes, (node).elements); -// case SyntaxKind.ArrayLiteralExpression: -// return visitNodes(cbNodes, (node).elements); -// case SyntaxKind.ObjectLiteralExpression: -// return visitNodes(cbNodes, (node).properties); -// case SyntaxKind.PropertyAccessExpression: -// return visitNode(cbNode, (node).expression) || -// visitNode(cbNode, (node).dotToken) || -// visitNode(cbNode, (node).name); -// case SyntaxKind.ElementAccessExpression: -// return visitNode(cbNode, (node).expression) || -// visitNode(cbNode, (node).argumentExpression); -// case SyntaxKind.CallExpression: -// case SyntaxKind.NewExpression: -// return visitNode(cbNode, (node).expression) || -// visitNodes(cbNodes, (node).typeArguments) || -// visitNodes(cbNodes, (node).arguments); -// case SyntaxKind.TaggedTemplateExpression: -// return visitNode(cbNode, (node).tag) || -// visitNode(cbNode, (node).template); -// case SyntaxKind.TypeAssertionExpression: -// return visitNode(cbNode, (node).type) || -// visitNode(cbNode, (node).expression); -// case SyntaxKind.ParenthesizedExpression: -// return visitNode(cbNode, (node).expression); -// case SyntaxKind.DeleteExpression: -// return visitNode(cbNode, (node).expression); -// case SyntaxKind.TypeOfExpression: -// return visitNode(cbNode, (node).expression); -// case SyntaxKind.VoidExpression: -// return visitNode(cbNode, (node).expression); -// case SyntaxKind.PrefixUnaryExpression: -// return visitNode(cbNode, (node).operand); -// case SyntaxKind.YieldExpression: -// return visitNode(cbNode, (node).asteriskToken) || -// visitNode(cbNode, (node).expression); -// case SyntaxKind.PostfixUnaryExpression: -// return visitNode(cbNode, (node).operand); -// case SyntaxKind.BinaryExpression: -// return visitNode(cbNode, (node).left) || -// visitNode(cbNode, (node).operatorToken) || -// visitNode(cbNode, (node).right); -// case SyntaxKind.ConditionalExpression: -// return visitNode(cbNode, (node).condition) || -// visitNode(cbNode, (node).questionToken) || -// visitNode(cbNode, (node).whenTrue) || -// visitNode(cbNode, (node).colonToken) || -// visitNode(cbNode, (node).whenFalse); -// case SyntaxKind.SpreadElementExpression: -// return visitNode(cbNode, (node).expression); -// case SyntaxKind.Block: -// case SyntaxKind.ModuleBlock: -// return visitNodes(cbNodes, (node).statements); -// case SyntaxKind.SourceFile: -// return visitNodes(cbNodes, (node).statements) || -// visitNode(cbNode, (node).endOfFileToken); -// case SyntaxKind.VariableStatement: -// return visitNodes(cbNodes, node.decorators) || -// visitNodes(cbNodes, node.modifiers) || -// visitNode(cbNode, (node).declarationList); -// case SyntaxKind.VariableDeclarationList: -// return visitNodes(cbNodes, (node).declarations); -// case SyntaxKind.ExpressionStatement: -// return visitNode(cbNode, (node).expression); -// case SyntaxKind.IfStatement: -// return visitNode(cbNode, (node).expression) || -// visitNode(cbNode, (node).thenStatement) || -// visitNode(cbNode, (node).elseStatement); -// case SyntaxKind.DoStatement: -// return visitNode(cbNode, (node).statement) || -// visitNode(cbNode, (node).expression); -// case SyntaxKind.WhileStatement: -// return visitNode(cbNode, (node).expression) || -// visitNode(cbNode, (node).statement); -// case SyntaxKind.ForStatement: -// return visitNode(cbNode, (node).initializer) || -// visitNode(cbNode, (node).condition) || -// visitNode(cbNode, (node).iterator) || -// visitNode(cbNode, (node).statement); -// case SyntaxKind.ForInStatement: -// return visitNode(cbNode, (node).initializer) || -// visitNode(cbNode, (node).expression) || -// visitNode(cbNode, (node).statement); -// case SyntaxKind.ForOfStatement: -// return visitNode(cbNode, (node).initializer) || -// visitNode(cbNode, (node).expression) || -// visitNode(cbNode, (node).statement); -// case SyntaxKind.ContinueStatement: -// case SyntaxKind.BreakStatement: -// return visitNode(cbNode, (node).label); -// case SyntaxKind.ReturnStatement: -// return visitNode(cbNode, (node).expression); -// case SyntaxKind.WithStatement: -// return visitNode(cbNode, (node).expression) || -// visitNode(cbNode, (node).statement); -// case SyntaxKind.SwitchStatement: -// return visitNode(cbNode, (node).expression) || -// visitNode(cbNode, (node).caseBlock); -// case SyntaxKind.CaseBlock: -// return visitNodes(cbNodes, (node).clauses); -// case SyntaxKind.CaseClause: -// return visitNode(cbNode, (node).expression) || -// visitNodes(cbNodes, (node).statements); -// case SyntaxKind.DefaultClause: -// return visitNodes(cbNodes, (node).statements); -// case SyntaxKind.LabeledStatement: -// return visitNode(cbNode, (node).label) || -// visitNode(cbNode, (node).statement); -// case SyntaxKind.ThrowStatement: -// return visitNode(cbNode, (node).expression); -// case SyntaxKind.TryStatement: -// return visitNode(cbNode, (node).tryBlock) || -// visitNode(cbNode, (node).catchClause) || -// visitNode(cbNode, (node).finallyBlock); -// case SyntaxKind.CatchClause: -// return visitNode(cbNode, (node).variableDeclaration) || -// visitNode(cbNode, (node).block); -// case SyntaxKind.Decorator: -// return visitNode(cbNode, (node).expression); -// case SyntaxKind.ClassDeclaration: -// case SyntaxKind.ClassExpression: -// return visitNodes(cbNodes, node.decorators) || -// visitNodes(cbNodes, node.modifiers) || -// visitNode(cbNode, (node).name) || -// visitNodes(cbNodes, (node).typeParameters) || -// visitNodes(cbNodes, (node).heritageClauses) || -// visitNodes(cbNodes, (node).members); -// case SyntaxKind.InterfaceDeclaration: -// return visitNodes(cbNodes, node.decorators) || -// visitNodes(cbNodes, node.modifiers) || -// visitNode(cbNode, (node).name) || -// visitNodes(cbNodes, (node).typeParameters) || -// visitNodes(cbNodes, (node).heritageClauses) || -// visitNodes(cbNodes, (node).members); -// case SyntaxKind.TypeAliasDeclaration: -// return visitNodes(cbNodes, node.decorators) || -// visitNodes(cbNodes, node.modifiers) || -// visitNode(cbNode, (node).name) || -// visitNode(cbNode, (node).type); -// case SyntaxKind.EnumDeclaration: -// return visitNodes(cbNodes, node.decorators) || -// visitNodes(cbNodes, node.modifiers) || -// visitNode(cbNode, (node).name) || -// visitNodes(cbNodes, (node).members); -// case SyntaxKind.EnumMember: -// return visitNode(cbNode, (node).name) || -// visitNode(cbNode, (node).initializer); -// case SyntaxKind.ModuleDeclaration: -// return visitNodes(cbNodes, node.decorators) || -// visitNodes(cbNodes, node.modifiers) || -// visitNode(cbNode, (node).name) || -// visitNode(cbNode, (node).body); -// case SyntaxKind.ImportEqualsDeclaration: -// return visitNodes(cbNodes, node.decorators) || -// visitNodes(cbNodes, node.modifiers) || -// visitNode(cbNode, (node).name) || -// visitNode(cbNode, (node).moduleReference); -// case SyntaxKind.ImportDeclaration: -// return visitNodes(cbNodes, node.decorators) || -// visitNodes(cbNodes, node.modifiers) || -// visitNode(cbNode, (node).importClause) || -// visitNode(cbNode, (node).moduleSpecifier); -// case SyntaxKind.ImportClause: -// return visitNode(cbNode, (node).name) || -// visitNode(cbNode, (node).namedBindings); -// case SyntaxKind.NamespaceImport: -// return visitNode(cbNode, (node).name); -// case SyntaxKind.NamedImports: -// case SyntaxKind.NamedExports: -// return visitNodes(cbNodes, (node).elements); -// case SyntaxKind.ExportDeclaration: -// return visitNodes(cbNodes, node.decorators) || -// visitNodes(cbNodes, node.modifiers) || -// visitNode(cbNode, (node).exportClause) || -// visitNode(cbNode, (node).moduleSpecifier); -// case SyntaxKind.ImportSpecifier: -// case SyntaxKind.ExportSpecifier: -// return visitNode(cbNode, (node).propertyName) || -// visitNode(cbNode, (node).name); -// case SyntaxKind.ExportAssignment: -// return visitNodes(cbNodes, node.decorators) || -// visitNodes(cbNodes, node.modifiers) || -// visitNode(cbNode, (node).expression) || -// visitNode(cbNode, (node).type); -// case SyntaxKind.TemplateExpression: -// return visitNode(cbNode, (node).head) || visitNodes(cbNodes, (node).templateSpans); -// case SyntaxKind.TemplateSpan: -// return visitNode(cbNode, (node).expression) || visitNode(cbNode, (node).literal); -// case SyntaxKind.ComputedPropertyName: -// return visitNode(cbNode, (node).expression); -// case SyntaxKind.HeritageClause: -// return visitNodes(cbNodes, (node).types); -// case SyntaxKind.HeritageClauseElement: -// return visitNode(cbNode, (node).expression) || -// visitNodes(cbNodes, (node).typeArguments); -// case SyntaxKind.ExternalModuleReference: -// return visitNode(cbNode, (node).expression); -// case SyntaxKind.MissingDeclaration: -// return visitNodes(cbNodes, node.decorators); -// } -// } diff --git a/lib/main/lang/modules/building.ts b/lib/main/lang/modules/building.ts deleted file mode 100644 index 1ae8a762e..000000000 --- a/lib/main/lang/modules/building.ts +++ /dev/null @@ -1,311 +0,0 @@ -import project = require('../core/project'); -import mkdirp = require('mkdirp'); -import path = require('path'); -import fs = require('fs'); -import {pathIsRelative, makeRelativePath} from "../../tsconfig/tsconfig"; -import {consistentPath} from "../../utils/fsUtil"; -import {createMap, assign} from "../utils"; -var findup = require('findup'); - -/** Lazy loaded babel tanspiler */ -let babels: { [key: string]: any } = {}; -/** Store babel configurations from .babelrc */ -let babelConfigs: { [key: string]: any } = {}; - -/** If we get a compile request for a ts file that is not in project. We return a js file with the following content */ -export const Not_In_Context = "/* NotInContext */"; - -export function diagnosticToTSError(diagnostic: ts.Diagnostic): CodeError { - var filePath = diagnostic.file.fileName; - var startPosition = diagnostic.file.getLineAndCharacterOfPosition(diagnostic.start); - var endPosition = diagnostic.file.getLineAndCharacterOfPosition(diagnostic.start + diagnostic.length); - - return { - filePath: filePath, - startPos: { line: startPosition.line, col: startPosition.character }, - endPos: { line: endPosition.line, col: endPosition.character }, - message: ts.flattenDiagnosticMessageText(diagnostic.messageText, '\n'), - preview: diagnostic.file.text.substr(diagnostic.start, diagnostic.length), - }; -} - -export function emitFile(proj: project.Project, filePath: string): EmitOutput { - var services = proj.languageService; - var output = services.getEmitOutput(filePath); - var emitDone = !output.emitSkipped; - var errors: CodeError[] = []; - - let sourceFile = services.getNonBoundSourceFile(filePath); - - // Emit is no guarantee that there are no errors - // so lets collect those - var allDiagnostics = services.getCompilerOptionsDiagnostics() - .concat(services.getSyntacticDiagnostics(filePath)) - .concat(services.getSemanticDiagnostics(filePath)); - allDiagnostics.forEach(diagnostic => { - // happens only for 'lib.d.ts' for some reason - if (!diagnostic.file) return; - - var startPosition = diagnostic.file.getLineAndCharacterOfPosition(diagnostic.start); - errors.push(diagnosticToTSError(diagnostic)); - }); - - /** - * Run an external transpiler - */ - { - let sourceMapContents: { [index: string]: any } = {}; - output.outputFiles.forEach(o => { - mkdirp.sync(path.dirname(o.name)); - runExternalTranspiler( - filePath, - sourceFile.text, - o, - proj, - sourceMapContents - ).then((additionalEmits) => { - if (!sourceMapContents[o.name] && !proj.projectFile.project.compilerOptions.noEmit) { - // .js.map files will be written as an "additional emit" later. - fs.writeFileSync(o.name, o.text, "utf8"); - } - - additionalEmits.forEach(a => { - mkdirp.sync(path.dirname(a.name)); - fs.writeFileSync(a.name, a.text, "utf8"); - }); - }); - }); - } - - // There is no *official* emit output for a `d.ts` - // but its nice to have a consistent world view in the rest of our code - var outputFiles = output.outputFiles.map((o) => o.name); - if (path.extname(filePath) == '.d.ts') { - outputFiles.push(filePath); - } - - return { - sourceFileName: filePath, - outputFiles: outputFiles, - success: emitDone && !errors.length, - errors: errors, - emitError: !emitDone - }; -} -export function getRawOutput(proj: project.Project, filePath: string): ts.EmitOutput { - let services = proj.languageService; - let output: ts.EmitOutput; - if (proj.includesSourceFile(filePath)) { - output = services.getEmitOutput(filePath); - } else { - output = { - outputFiles: [{ name: filePath, text: Not_In_Context, writeByteOrderMark: false }], - emitSkipped: true - } - } - return output; -} - -function getBabelInstance(projectDirectory: string) { - return new Promise(resolve => { - if (!babels[projectDirectory]) { - findup(projectDirectory, 'node_modules/babel-core', function(err: any, dir: string) { - if (err) { - findup(projectDirectory, 'node_modules/babel', function(err: any, dir: string) { - if (err) { - babels[projectDirectory] = require('babel'); - } else { - babels[projectDirectory] = require(path.join(dir, 'node_modules/babel')); - } - - resolve(babels[projectDirectory]); - }); - } else { - babels[projectDirectory] = require(path.join(dir, 'node_modules/babel-core')); - resolve(babels[projectDirectory]); - } - }); - } else { - resolve(babels[projectDirectory]); - } - }).then(babel => { - return new Promise(resolve => { - findup(projectDirectory, '.babelrc', function(err: any, dir) { - if (err) return resolve(babel); - - fs.readFile(path.join(dir, '.babelrc'), function(err, data) { - try { - babelConfigs[projectDirectory] = JSON.parse(data.toString()); - } catch (e) { } - - resolve(babel); - }); - }); - }); - }); -} - -function runExternalTranspiler(sourceFileName: string, - sourceFileText: string, - outputFile: ts.OutputFile, - project: project.Project, - sourceMapContents: { [index: string]: any }): Promise { - - if (!isJSFile(outputFile.name) && !isJSSourceMapFile(outputFile.name)) { - return Promise.resolve([]); - } - - let settings = project.projectFile.project; - let externalTranspiler = settings.externalTranspiler; - if (!externalTranspiler) { - return Promise.resolve([]); - } - - if (isJSSourceMapFile(outputFile.name)) { - let sourceMapPayload = JSON.parse(outputFile.text); - let jsFileName = consistentPath(path.resolve(path.dirname(outputFile.name), sourceMapPayload.file)); - sourceMapContents[outputFile.name] = { jsFileName: jsFileName, sourceMapPayload }; - return Promise.resolve([]); - } - - if (typeof externalTranspiler === 'string') { - externalTranspiler = { - name: externalTranspiler as string, - options: {} - } - } - - // We need this type guard to narrow externalTranspiler's type - if (typeof externalTranspiler === 'object') { - if (externalTranspiler.name.toLocaleLowerCase() === "babel") { - return getBabelInstance(project.projectFile.projectFileDirectory).then((babel) => { - - let babelOptions: any = assign(babelConfigs[project.projectFile.projectFileDirectory] || {}, (externalTranspiler as any).options || {}, { - filename: outputFile.name - }); - - let sourceMapFileName = getJSMapNameForJSFile(outputFile.name); - - if (sourceMapContents[sourceMapFileName]) { - babelOptions.inputSourceMap = sourceMapContents[sourceMapFileName].sourceMapPayload; - let baseName = path.basename(sourceFileName); - // NOTE: Babel generates invalid source map without consistent `sources` and `file`. - babelOptions.inputSourceMap.sources = [baseName]; - babelOptions.inputSourceMap.file = baseName; - } - if (settings.compilerOptions.sourceMap) { - babelOptions.sourceMaps = true; - } - if (settings.compilerOptions.inlineSourceMap) { - babelOptions.sourceMaps = "inline"; - } - if (!settings.compilerOptions.removeComments) { - babelOptions.comments = true; - } - - var directory = process.cwd(); - process.chdir(project.projectFile.projectFileDirectory); - let babelResult = babel.transform(outputFile.text, babelOptions); - process.chdir(directory); - outputFile.text = babelResult.code; - - if (babelResult.map && settings.compilerOptions.sourceMap) { - let additionalEmit: ts.OutputFile = { - name: sourceMapFileName, - text: JSON.stringify(babelResult.map), - writeByteOrderMark: settings.compilerOptions.emitBOM - }; - - if (additionalEmit.name === "") { - // can't emit a blank file name - this should only be reached if the TypeScript - // language service returns the .js file before the .js.map file. - console.warn(`The TypeScript language service did not yet provide a .js.map name for file ${outputFile.name}`); - return []; - } - - return [additionalEmit]; - } - - return []; - }); - } - } - - function getJSMapNameForJSFile(jsFileName: string) { - for (let jsMapName in sourceMapContents) { - if (sourceMapContents.hasOwnProperty(jsMapName)) { - if (sourceMapContents[jsMapName].jsFileName === jsFileName) { - return jsMapName; - } - } - } - return ""; - } -} - -function isJSFile(fileName: string) { - return (path.extname(fileName).toLocaleLowerCase() === ".js"); -} - -function isJSSourceMapFile(fileName: string) { - let lastExt = path.extname(fileName); - if (lastExt === ".map") { - return isJSFile(fileName.substr(0, fileName.length - 4)); - } - return false; -} - - -import dts = require("../../tsconfig/dts-generator"); - -export function emitDts(proj: project.Project) { - - if (!proj.projectFile.project) return; - if (proj.projectFile.project.compilerOptions.outFile) return; - if (!proj.projectFile.project.package) return; - if (!proj.projectFile.project.package.directory) return; - if (!proj.projectFile.project.package.definition) return; - - // Determined from package.json typescript.definition property - var outFile = path.resolve(proj.projectFile.project.package.directory, './', proj.projectFile.project.package.definition) - - // This is package.json directory - var baseDir = proj.projectFile.project.package.directory; - - // The name of the package (of course!) - var name = proj.projectFile.project.package.name; - - // The main file - var main: string = proj.projectFile.project.package.main; - - // We need to find a ts file for this `main` and we also need to get its - if (main) { - // if path is relative we need to replace that section with 'name' - // ./foo => 'something/foo' - main = name + '/' + consistentPath(main.replace('./', '')); - - // Replace trailing `.js` with nothing - main = main.replace(/\.*.js$/g, ''); - } - - // Typings become externs - // And these are relative to the output .d.ts we are generating - var externs = proj.projectFile.project.typings; - - // The files - var files = proj.projectFile.project.files; - - dts.generate({ - baseDir, - files, - externs, - name: name, - - target: proj.projectFile.project.compilerOptions.target, - out: outFile, - - main: main, - - outDir: proj.projectFile.project.compilerOptions.outDir - }) -} diff --git a/lib/main/lang/modules/formatting.ts b/lib/main/lang/modules/formatting.ts deleted file mode 100644 index c77a85159..000000000 --- a/lib/main/lang/modules/formatting.ts +++ /dev/null @@ -1,29 +0,0 @@ -import project = require('../core/project'); - -export function formatDocument(proj: project.Project, filePath: string): CodeEdit[] { - var textChanges = proj.languageService.getFormattingEditsForDocument(filePath, proj.projectFile.project.formatCodeOptions); - - var edits: CodeEdit[] = textChanges.map(change=> { - return { - start: proj.languageServiceHost.getPositionFromIndex(filePath, change.span.start), - end: proj.languageServiceHost.getPositionFromIndex(filePath, change.span.start + change.span.length), - newText: change.newText - }; - }); - - return edits; -} -export function formatDocumentRange(proj: project.Project, filePath: string, start: EditorPosition, end: EditorPosition): CodeEdit[] { - var st = proj.languageServiceHost.getIndexFromPosition(filePath, start); - var ed = proj.languageServiceHost.getIndexFromPosition(filePath, end); - var textChanges = proj.languageService.getFormattingEditsForRange(filePath, st, ed, proj.projectFile.project.formatCodeOptions); - - var edits: CodeEdit[] = textChanges.map(change=> { - return { - start: proj.languageServiceHost.getPositionFromIndex(filePath, change.span.start), - end: proj.languageServiceHost.getPositionFromIndex(filePath, change.span.start + change.span.length), - newText: change.newText - }; - }); - return edits; -} diff --git a/lib/main/lang/modules/getPathCompletions.ts b/lib/main/lang/modules/getPathCompletions.ts deleted file mode 100644 index 4d79adebb..000000000 --- a/lib/main/lang/modules/getPathCompletions.ts +++ /dev/null @@ -1,84 +0,0 @@ -import * as path from "path"; -import {Project} from "../core/project"; -import * as tsconfig from "../../tsconfig/tsconfig"; -import * as utils from "../utils"; -var fuzzaldrin: { filter: (list: any[], prefix: string, property?: { key: string }) => any } = require('fuzzaldrin'); - -/** From https://github.com/Microsoft/TypeScript/pull/2173/files */ -function getExternalModuleNames(program: ts.Program): string[] { - var entries: string[] = []; - - program.getSourceFiles().forEach(sourceFile => { - - // Look for ambient external module declarations - ts.forEachChild(sourceFile, child => { - if (child.kind === ts.SyntaxKind.ModuleDeclaration && (child).name.kind === ts.SyntaxKind.StringLiteral) { - entries.push((child).name.text); - } - }); - }); - - return entries; -} - -function formatImportPath(sourcePath: string): string { - sourcePath = sourcePath.replace(/\.d$/, ""); // tsconfig.removeExt can convert d.ts file path into the filepath end with `.d`; - sourcePath = sourcePath.replace(/.*\/node_modules\//, ""); - return sourcePath; -} - -export interface GetRelativePathsInProjectResponse { - files: { - name: string; - relativePath: string; - fullPath: string; - }[]; - endsInPunctuation: boolean; -} - -export interface GetPathCompletions { - project: Project; - filePath: string; - prefix: string; - includeExternalModules: boolean; -} - -export function getPathCompletions(query: GetPathCompletions): GetRelativePathsInProjectResponse { - var project = query.project; - var sourceDir = path.dirname(query.filePath); - var filePaths = project.projectFile.project.files.filter(p => p !== query.filePath); - var files: { - name: string; - relativePath: string; - fullPath: string; - }[] = []; - - if (query.includeExternalModules) { - var externalModules = getExternalModuleNames(project.languageService.getProgram()); - externalModules.forEach(e => files.push({ - name: `${e}`, - relativePath: e, - fullPath: e - })); - } - - filePaths.forEach(p => { - files.push({ - name: path.basename(p, '.ts'), - relativePath: formatImportPath(tsconfig.removeExt(tsconfig.makeRelativePath(sourceDir, p))), - fullPath: p - }); - }); - - var endsInPunctuation: boolean = utils.prefixEndsInPunctuation(query.prefix); - - if (!endsInPunctuation) - files = fuzzaldrin.filter(files, query.prefix, { key: 'name' }); - - var response: GetRelativePathsInProjectResponse = { - files: files, - endsInPunctuation: endsInPunctuation - }; - - return response; -} \ No newline at end of file diff --git a/lib/main/lang/modules/moveFiles.ts b/lib/main/lang/modules/moveFiles.ts deleted file mode 100644 index 73a5f8f31..000000000 --- a/lib/main/lang/modules/moveFiles.ts +++ /dev/null @@ -1,59 +0,0 @@ -/** - * Gets the refactorings you would need if you move files around - */ - -import {Refactoring} from "../fixmyts/quickFix"; -import {getSourceFileImportsWithTextRange} from "../fixmyts/astUtils"; -import * as path from "path"; -import { -removeExt, -pathIsRelative, -makeRelativePath -} from "../../tsconfig/tsconfig"; -import {consistentPath} from "../../utils/fsUtil"; - -/** - * will return the refactorings for what needs to change in the source files if the old path becomes new path - */ -export function getRenameFilesRefactorings(program: ts.Program, oldDirectoryOrFile: string, newDirectoryOrFile: string): Refactoring[] { - oldDirectoryOrFile = consistentPath(oldDirectoryOrFile); - newDirectoryOrFile = consistentPath(newDirectoryOrFile); - - var oldFileNoExt = removeExt(oldDirectoryOrFile); - var newFileNoExt = removeExt(newDirectoryOrFile); - - /** - * Go through all the files in the program and find the ones that referece the "oldDirectoryOrFile" - * The refactoring is to just find a relative path to the newDirectoryOrFile (just the contents of the string without quotes) - */ - - var refactorings: Refactoring[] = []; - - var sourceFiles = program.getSourceFiles(); - - sourceFiles.forEach(sourceFile => { - let imports = getSourceFileImportsWithTextRange(sourceFile) - .filter((fileReference) => pathIsRelative(fileReference.text)) - .map(ref=> { - return { - path: consistentPath(path.resolve(path.dirname(sourceFile.fileName), ref.text)), - range: ref.range - }; - }) - var matches = imports.filter(f=> f.path == oldFileNoExt); - if (matches.length) { - for (let match of matches) { - refactorings.push({ - filePath: sourceFile.fileName, - span: { - start: match.range.pos, - length: match.range.end - match.range.pos - }, - newText: makeRelativePath(path.dirname(sourceFile.fileName), newFileNoExt) - }); - } - } - }); - - return refactorings; -} diff --git a/lib/main/lang/modules/programDependencies.ts b/lib/main/lang/modules/programDependencies.ts deleted file mode 100644 index edf40952d..000000000 --- a/lib/main/lang/modules/programDependencies.ts +++ /dev/null @@ -1,36 +0,0 @@ - -import {TypeScriptProjectFileDetails, pathIsRelative} from "../../tsconfig/tsconfig"; -import {consistentPath} from "../../utils/fsUtil"; -import tsconfig = require("../../tsconfig/tsconfig"); -import * as path from "path"; -import * as fs from "fs"; -import {getSourceFileImports} from "../fixmyts/astUtils"; - -export default function getDependencies(projectFile: TypeScriptProjectFileDetails, program: ts.Program): FileDependency[] { - var links: FileDependency[] = []; - var projectDir = projectFile.projectFileDirectory; - for (let file of program.getSourceFiles()) { - let filePath = file.fileName; - var dir = path.dirname(filePath); - - var targets = getSourceFileImports(file) - .filter((fileReference) => pathIsRelative(fileReference)) - .map(fileReference => { - var file = path.resolve(dir, fileReference + '.ts'); - if (!fs.existsSync(file)) { - file = path.resolve(dir, fileReference + '.d.ts'); - } - return file; - }); - - for (let target of targets) { - var targetPath = consistentPath(path.relative(projectDir, consistentPath(target))); - var sourcePath = consistentPath(path.relative(projectDir, filePath)); - links.push({ - sourcePath, - targetPath - }) - } - } - return links; -} diff --git a/lib/main/lang/projectCache.ts b/lib/main/lang/projectCache.ts deleted file mode 100644 index cfc4b621f..000000000 --- a/lib/main/lang/projectCache.ts +++ /dev/null @@ -1,238 +0,0 @@ -import fs = require("fs"); -import path = require("path"); -import tsconfig = require("../tsconfig/tsconfig"); -import {Project, languageServiceHost} from "./core/project"; -import * as fsu from "../utils/fsUtil"; - -import queryParent = require('../../worker/queryParent'); -import workerLib = require('../../worker/lib/workerLib'); -export {queryParent}; -// pushed in by child.ts -// If we are in a child context we patch the functions to execute via IPC. -// Otherwise we would call them directly. -var child: workerLib.Child; -export function fixChild(childInjected: typeof child) { - child = childInjected; - queryParent.echoNumWithModification = child.sendToIpc(queryParent.echoNumWithModification); - queryParent.getUpdatedTextForUnsavedEditors = child.sendToIpc(queryParent.getUpdatedTextForUnsavedEditors); - queryParent.getOpenEditorPaths = child.sendToIpc(queryParent.getOpenEditorPaths); - queryParent.setConfigurationError = child.sendToIpc(queryParent.setConfigurationError); - queryParent.notifySuccess = child.sendToIpc(queryParent.notifySuccess); - queryParent.buildUpdate = child.sendToIpc(queryParent.buildUpdate); -} - -/** utility interface **/ -export interface FilePathQuery { - filePath: string; -} - - -/** mutate and fix the filePath silently */ -export function consistentPath(query: FilePathQuery) { - if (!query.filePath) return; - query.filePath = fsu.consistentPath(query.filePath); -} - - -//////////////////////////////////////////////////////////////////////////////////////// -//////////////// MAINTAIN A HOT CACHE TO DECREASE FILE LOOKUPS ///////////////////////// -//////////////////////////////////////////////////////////////////////////////////////// - -var projectByProjectFilePath: { [projectFilePath: string]: Project } = {} - -/** - * filePath is : - * the project file path - * Or any source ts file path - */ -var projectByFilePath: { [filePath: string]: Project } = {} - -var watchingProjectFile: { [projectFilePath: string]: boolean } = {} -function watchProjectFileIfNotDoingItAlready(projectFilePath: string) { - - // Don't watch lib.d.ts and other - // projects that are "in memory" only - if (!fs.existsSync(projectFilePath)) { - return; - } - - if (watchingProjectFile[projectFilePath]) return; // Only watch once - watchingProjectFile[projectFilePath] = true; - - fs.watch(projectFilePath, { persistent: false }, () => { - // if file no longer exists - if (!fs.existsSync(projectFilePath)) { - // if we have a cache for it then clear it - var project = projectByProjectFilePath[projectFilePath]; - if (project) { - var files = project.projectFile.project.files; - - delete projectByProjectFilePath[projectFilePath]; - files.forEach((file) => delete projectByFilePath[file]); - } - return; - } - - // Reload the project file from the file system and re cache it - try { - var projectFile = getOrCreateProjectFile(projectFilePath); - cacheAndCreateProject(projectFile); - queryParent.setConfigurationError({ projectFilePath: projectFile.projectFilePath, error: null }); - } - catch (ex) { - // Keep failing silently - // TODO: reuse reporting logic - } - }); -} - -/** We are loading the project from file system. - This might not match what we have in the editor memory, so query those as well -*/ -export function cacheAndCreateProject(projectFile: tsconfig.TypeScriptProjectFileDetails) { - var project = projectByProjectFilePath[projectFile.projectFilePath] = new Project(projectFile); - projectFile.project.files.forEach((file) => projectByFilePath[file] = project); - - // query the parent for unsaved changes - // We do this lazily - queryParent.getUpdatedTextForUnsavedEditors({}) - .then(resp=> { - resp.editors.forEach(e=> { - consistentPath(e); - project.languageServiceHost.updateScript(e.filePath, e.text); - }); - }); - - watchProjectFileIfNotDoingItAlready(projectFile.projectFilePath); - - return project; -} - -/** - * This explicilty loads the project from the filesystem - * For (lib.d.ts) and other (.d.ts files where project is not found) creation is done in memory - */ -export function getOrCreateProjectFile(filePath: string): tsconfig.TypeScriptProjectFileDetails { - - try { - // If we are asked to look at stuff in lib.d.ts create its own project - if (path.dirname(filePath) == languageServiceHost.typescriptDirectory) { - return tsconfig.getDefaultInMemoryProject(filePath); - } - - var projectFile = tsconfig.getProjectSync(filePath); - queryParent.setConfigurationError({ projectFilePath: projectFile.projectFilePath, error: null }); - return projectFile; - } catch (ex) { - var err: Error = ex; - if (err.message === tsconfig.errors.GET_PROJECT_NO_PROJECT_FOUND) { - // If we have a .d.ts file then it is its own project and return - if (tsconfig.endsWith(filePath.toLowerCase(), '.d.ts')) { - return tsconfig.getDefaultInMemoryProject(filePath); - } - // Otherwise report error - else { - // var projectFile = tsconfig.createProjectRootSync(filePath); - // queryParent.notifySuccess({ message: 'AtomTS: tsconfig.json file created:
    ' + projectFile.projectFilePath }); - // queryParent.setConfigurationError({ projectFilePath: projectFile.projectFilePath, error: null }); - // return projectFile; - let details: tsconfig.GET_PROJECT_NO_PROJECT_FOUND_Details = ex.details; - queryParent.setConfigurationError({ - projectFilePath: details.projectFilePath, - error: { - message: ex.message, - details: ex.details - } - }); - } - } - if (ex.message === tsconfig.errors.GET_PROJECT_JSON_PARSE_FAILED) { - var details0: tsconfig.GET_PROJECT_JSON_PARSE_FAILED_Details = ex.details; - queryParent.setConfigurationError({ - projectFilePath: details0.projectFilePath, - error: { - message: ex.message, - details: ex.details - } - }); - // Watch this project file to see if user fixes errors - watchProjectFileIfNotDoingItAlready(details0.projectFilePath); - } - if (ex.message === tsconfig.errors.GET_PROJECT_PROJECT_FILE_INVALID_OPTIONS) { - var details1: tsconfig.GET_PROJECT_PROJECT_FILE_INVALID_OPTIONS_Details = ex.details; - queryParent.setConfigurationError({ - projectFilePath: details1.projectFilePath, - error: { - message: ex.message, - details: ex.details - } - }); - // Watch this project file to see if user fixes errors - watchProjectFileIfNotDoingItAlready(details1.projectFilePath); - } - if (ex.message === tsconfig.errors.GET_PROJECT_GLOB_EXPAND_FAILED) { - var details2: tsconfig.GET_PROJECT_GLOB_EXPAND_FAILED_Details = ex.details; - queryParent.setConfigurationError({ - projectFilePath: details2.projectFilePath, - error: { - message: ex.message, - details: ex.details - } - }); - // Watch this project file to see if user fixes errors - watchProjectFileIfNotDoingItAlready(details2.projectFilePath); - } - throw ex; - } -} - -/** Looks into the cache and if not found caches it */ -export function getOrCreateProject(filePath: string) { - - // For transform files we check for the file with .ts extension in cache - if (tsconfig.endsWith(filePath, '.tst')) { - filePath = filePath + '.ts'; - } - - filePath = fsu.consistentPath(filePath); - if (projectByFilePath[filePath]) { - // we are in good shape - return projectByFilePath[filePath]; - } - else { - // We are in a bad shape. Why didn't we know of this file before? - // Even if we find the projectFile we should invalidate it. - var projectFile = getOrCreateProjectFile(filePath); - var project = cacheAndCreateProject(projectFile); - return project; - } -} - - -export interface SoftResetQuery { - filePath: string; - text: string; -} -export function resetCache(query: SoftResetQuery) { - // clear the cache - projectByProjectFilePath = {} - projectByFilePath = {} - - if (query.filePath) { - consistentPath(query); - - // Create cache for this file - var project = getOrCreateProject(query.filePath); - project.languageServiceHost.updateScript(query.filePath, query.text); - } - - // Also update the cache for any other unsaved editors - queryParent.getUpdatedTextForUnsavedEditors({}) - .then(resp=> { - resp.editors.forEach(e=> { - consistentPath(e); - var proj = getOrCreateProject(e.filePath); - proj.languageServiceHost.updateScript(e.filePath, e.text); - }); - }); -} diff --git a/lib/main/lang/projectService.ts b/lib/main/lang/projectService.ts deleted file mode 100644 index ae623ae38..000000000 --- a/lib/main/lang/projectService.ts +++ /dev/null @@ -1,1062 +0,0 @@ - -import * as fsu from "../utils/fsUtil"; -import fs = require('fs'); -import path = require('path'); -import os = require('os'); -import child_process = require("child_process"); -import mkdirp = require('mkdirp'); -var fuzzaldrin: { filter: (list: any[], prefix: string, property?: { key: string }) => any } = require('fuzzaldrin'); -import {isTransformerFile} from "./transformers/transformer"; -import * as transformer from "./transformers/transformer"; - -import tsconfig = require('../tsconfig/tsconfig'); -import * as fsUtil from "../utils/fsUtil"; - -import utils = require('./utils'); -import project = require('./core/project'); -import Project = project.Project; -import languageServiceHost = project.languageServiceHost; - -var resolve: typeof Promise.resolve = Promise.resolve.bind(Promise); - -import {consistentPath, -FilePathQuery, -queryParent, -getOrCreateProject, -SoftResetQuery, -resetCache} -from "./projectCache"; - -//////////////////////////////////////////////////////////////////////////////////////// -//////////////// MECHANISM FOR THE CHILD TO QUERY THE PARENT /////////////////////////// -//////////////////////////////////////////////////////////////////////////////////////// - -//-------------------------------------------------------------------------- -// Utility Interfaces -//-------------------------------------------------------------------------- - -/** utility interface **/ -interface FilePathPositionQuery { - filePath: string; - position: number; -} - -interface TextSpan { - start: number; - length: number; -} -function textSpan(span: ts.TextSpan): TextSpan { - return { - start: span.start, - length: span.length - } -} - -//////////////////////////////////////////////////////////////////////////////////////// -//////////////////////////// QUERY / RESPONSE ////////////////////////////////////////// -//////////////////////////////////////////////////////////////////////////////////////// - -export interface Echo { - echo: any; - num: number; -} -export function echo(data: Echo): Promise { - return queryParent.echoNumWithModification({ num: data.num }).then((resp) => { - data.num = resp.num; - return data; - }); -} - -export interface QuickInfoQuery extends FilePathPositionQuery { } -export interface QuickInfoResponse { - valid: boolean; // Do we have a valid response for this query - name?: string; - comment?: string; -} -export function quickInfo(query: QuickInfoQuery): Promise { - consistentPath(query); - var project = getOrCreateProject(query.filePath); - if (!project.includesSourceFile(query.filePath)) { - return Promise.resolve({ valid: false }); - } - var info = project.languageService.getQuickInfoAtPosition(query.filePath, query.position); - if (!info) { - return Promise.resolve({ valid: false }); - } else { - return resolve({ - valid: true, - name: ts.displayPartsToString(info.displayParts || []), - comment: ts.displayPartsToString(info.documentation || []) - }); - } -} - -export interface BuildQuery extends FilePathQuery { } -export interface BuildResponse { - tsFilesWithInvalidEmit: string[]; - tsFilesWithValidEmit: string[]; - buildOutput: BuildOutput; -} -import building = require('./modules/building'); -export function build(query: BuildQuery): Promise { - consistentPath(query); - var proj = getOrCreateProject(query.filePath); - - let filesToEmit = proj.projectFile.project.files.filter(fte => !fte.toLowerCase().endsWith('.json')); - /** I am assuming there was at least one file. How else would we even get here? */ - filesToEmit = proj.projectFile.project.compilerOptions.outFile ? [filesToEmit[0]] : filesToEmit; - - let totalCount = filesToEmit.length; - var builtCount = 0; - var errorCount = 0; - let outputs: EmitOutput[] = filesToEmit.map((filePath) => { - var output = building.emitFile(proj, filePath); - builtCount++; - errorCount = errorCount + output.errors.length; - queryParent.buildUpdate({ - totalCount, - builtCount, - errorCount, - firstError: errorCount && !(errorCount - output.errors.length), - filePath, - errorsInFile: output.errors - }); - return output; - }); - - // Also optionally emit a root dts: - building.emitDts(proj); - - // If there is a post build script to run ... run it - if (proj.projectFile.project.scripts - && proj.projectFile.project.scripts.postbuild) { - child_process.exec(proj.projectFile.project.scripts.postbuild, { cwd: proj.projectFile.projectFileDirectory }, (err, stdout, stderr) => { - if (err) { - console.error('postbuild failed!'); - console.error(proj.projectFile.project.scripts.postbuild); - console.error(stderr); - } - }); - } - - let tsFilesWithInvalidEmit = outputs - .filter((o) => o.emitError) - .map((o) => o.sourceFileName); - let tsFilesWithValidEmit = outputs - .filter((o) => !o.emitError) - .map((o) => o.sourceFileName); - - return resolve({ - tsFilesWithInvalidEmit: tsFilesWithInvalidEmit, - tsFilesWithValidEmit: tsFilesWithValidEmit, - buildOutput: { - outputs: outputs, - counts: { - inputFiles: proj.projectFile.project.files.length, - outputFiles: utils.selectMany(outputs.map((out) => out.outputFiles)).length, - errors: errorCount, - emitErrors: outputs.filter(out => out.emitError).length - } - } - }); -} - -export interface GetCompletionsAtPositionQuery extends FilePathPositionQuery { - prefix: string; -} -export interface Completion { - name?: string; // stuff like "toString" - kind?: string; // stuff like "var" - comment?: string; // the docComment if any - display?: string; // This is either displayParts (for functions) or just the kind duplicated - - /** If snippet is specified then the above stuff is ignored */ - snippet?: string; -} -export interface GetCompletionsAtPositionResponse { - completions: Completion[]; - endsInPunctuation: boolean; -} - -export function getCompletionsAtPosition(query: GetCompletionsAtPositionQuery): Promise { - consistentPath(query); - var filePath = query.filePath, position = query.position, prefix = query.prefix; - var project = getOrCreateProject(filePath); - - // For transformer files - filePath = transformer.getPseudoFilePath(filePath); - - var completions: ts.CompletionInfo = project.languageService.getCompletionsAtPosition( - filePath, position); - var completionList = completions ? completions.entries.filter(x=> !!x) : []; - var endsInPunctuation = utils.prefixEndsInPunctuation(prefix); - - if (prefix.length && !endsInPunctuation) { - // Didn't work good for punctuation - completionList = fuzzaldrin.filter(completionList, prefix, { key: 'name' }); - } - - /** Doing too many suggestions is slowing us down in some cases */ - let maxSuggestions = 50; - /** Doc comments slow us down tremendously */ - let maxDocComments = 10; - - // limit to maxSuggestions - if (completionList.length > maxSuggestions) completionList = completionList.slice(0, maxSuggestions); - - // Potentially use it more aggresively at some point - function docComment(c: ts.CompletionEntry): { display: string; comment: string; } { - var completionDetails = project.languageService.getCompletionEntryDetails(filePath, position, c.name); - - // Show the signatures for methods / functions - var display: string; - if (c.kind == "method" || c.kind == "function" || c.kind == "property") { - let parts = completionDetails.displayParts || []; - // don't show `(method)` or `(function)` as that is taken care of by `kind` - if (parts.length > 3) { - parts = parts.splice(3); - } - display = ts.displayPartsToString(parts); - } - else { - display = ''; - } - var comment = (display ? display + '\n' : '') + ts.displayPartsToString(completionDetails.documentation || []); - - return { display: display, comment: comment }; - } - - var completionsToReturn: Completion[] = completionList.map((c, index) => { - if (index < maxDocComments) { - var details = docComment(c); - } - else { - details = { - display: '', - comment: '' - } - } - return { - name: c.name, - kind: c.kind, - comment: details.comment, - display: details.display - }; - }); - - if (query.prefix == '(') { - var signatures = project.languageService.getSignatureHelpItems(query.filePath, query.position); - if (signatures && signatures.items) { - signatures.items.forEach((item) => { - var snippet: string = item.parameters.map((p, i) => { - var display = '${' + (i + 1) + ':' + ts.displayPartsToString(p.displayParts) + '}'; - if (i === signatures.argumentIndex) { - return display; - } - return display; - }).join(ts.displayPartsToString(item.separatorDisplayParts)); - - // We do not use the label for now. But it looks too good to kill off - var label: string = ts.displayPartsToString(item.prefixDisplayParts) - + snippet - + ts.displayPartsToString(item.suffixDisplayParts); - - completionsToReturn.unshift({ snippet }); - }); - } - } - - return resolve({ - completions: completionsToReturn, - endsInPunctuation: endsInPunctuation - }); -} - -export interface GetSignatureHelpQuery extends FilePathPositionQuery { } -export interface SignatureHelp { - -} -export interface GetSignatureHelpResponse { - signatureHelps: SignatureHelp[]; -} -export function getSignatureHelps(query: GetSignatureHelpQuery): Promise { - consistentPath(query); - var project = getOrCreateProject(query.filePath); - var signatureHelpItems = project.languageService.getSignatureHelpItems(query.filePath, query.position); - - if (!signatureHelpItems || !signatureHelpItems.items || !signatureHelpItems.items.length) - return resolve({ signatureHelps: [] }); - - // TODO: WIP - return signatureHelpItems.items; -} - -export interface EmitFileQuery extends FilePathQuery { } -export interface EmitFileResponse extends EmitOutput { } -export function emitFile(query: EmitFileQuery): Promise { - consistentPath(query); - var filePath = transformer.getPseudoFilePath(query.filePath); - return resolve(building.emitFile(getOrCreateProject(filePath), filePath)); -} - -import formatting = require('./modules/formatting'); -export interface FormatDocumentQuery extends FilePathQuery { -} -export interface FormatDocumentResponse { - edits: CodeEdit[]; -} -export function formatDocument(query: FormatDocumentQuery): Promise { - consistentPath(query); - var proj = getOrCreateProject(query.filePath); - return resolve({ edits: formatting.formatDocument(proj, query.filePath) }); -} - -export interface FormatDocumentRangeQuery extends FilePathQuery { - start: EditorPosition; - end: EditorPosition; -} -export interface FormatDocumentRangeResponse { edits: CodeEdit[]; } -export function formatDocumentRange(query: FormatDocumentRangeQuery): Promise { - consistentPath(query); - var proj = getOrCreateProject(query.filePath); - return resolve({ edits: formatting.formatDocumentRange(proj, query.filePath, query.start, query.end) }); -} - -export interface GetDefinitionsAtPositionQuery extends FilePathPositionQuery { } -export interface GetDefinitionsAtPositionResponse { - projectFileDirectory: string; - definitions: { - filePath: string; - position: EditorPosition - }[] -} -export function getDefinitionsAtPosition(query: GetDefinitionsAtPositionQuery): Promise { - consistentPath(query); - var project = getOrCreateProject(query.filePath); - var definitions = project.languageService.getDefinitionAtPosition(query.filePath, query.position); - var projectFileDirectory = project.projectFile.projectFileDirectory; - if (!definitions || !definitions.length) return resolve({ projectFileDirectory: projectFileDirectory, definitions: [] }); - - return resolve({ - projectFileDirectory: projectFileDirectory, - definitions: definitions.map(d=> { - // If we can get the filename *we are in the same program :P* - var pos = project.languageServiceHost.getPositionFromIndex(d.fileName, d.textSpan.start); - return { - filePath: d.fileName, - position: pos - }; - }) - }); -} - -export interface UpdateTextQuery extends FilePathQuery { - text: string; -} -export function updateText(query: UpdateTextQuery): Promise { - consistentPath(query); - var lsh = getOrCreateProject(query.filePath).languageServiceHost; - - // Apply the update to the pseudo ts file - var filePath = transformer.getPseudoFilePath(query.filePath); - lsh.updateScript(filePath, query.text); - return resolve({}); -} - -export interface EditTextQuery extends FilePathQuery { - start: EditorPosition; - end: EditorPosition; - newText: string; -} -export function editText(query: EditTextQuery): Promise { - consistentPath(query); - let project = getOrCreateProject(query.filePath); - if (project.includesSourceFile(query.filePath)) { - let lsh = project.languageServiceHost; - // Apply the update to the pseudo ts file - let filePath = transformer.getPseudoFilePath(query.filePath); - lsh.editScript(filePath, query.start, query.end, query.newText); - } - return resolve({}); -} - -/** Utility function */ -function getDiagnositcsByFilePath(query: FilePathQuery) { - consistentPath(query); - var project = getOrCreateProject(query.filePath); - var diagnostics = project.languageService.getSyntacticDiagnostics(query.filePath); - if (diagnostics.length === 0) { - diagnostics = project.languageService.getSemanticDiagnostics(query.filePath); - } - return diagnostics; -} - -export function errorsForFile(query: FilePathQuery): Promise<{ - errors: CodeError[] -}> { - consistentPath(query); - let project: project.Project; - - try { - project = getOrCreateProject(query.filePath); - } catch (ex) { - return resolve({ errors: [] }); - } - - // for file path errors in transformer - if (isTransformerFile(query.filePath)) { - let filePath = transformer.getPseudoFilePath(query.filePath); - let errors = getDiagnositcsByFilePath({ filePath }).map(building.diagnosticToTSError); - errors.forEach(error => { - error.filePath = query.filePath; - }); - return resolve({ errors: errors }); - } - else { - let result: CodeError[]; - - if (project.includesSourceFile(query.filePath)) { - result = getDiagnositcsByFilePath(query).map(building.diagnosticToTSError); - } else { - result = notInContextResult(query.filePath); - } - - return resolve({ errors: result }); - } -} - -function notInContextResult(fileName: string) { - return [{ - filePath: fileName, - startPos: { line: 0, col: 0 }, - endPos: { line: 0, col: 0 }, - message: "The file \"" + fileName + "\" is not included in the TypeScript compilation context. If this is not intended, please check the \"files\" or \"filesGlob\" section of your tsconfig.json file.", - preview: "" - }]; -} - -export interface GetRenameInfoQuery extends FilePathPositionQuery { } -export interface GetRenameInfoResponse { - canRename: boolean; - localizedErrorMessage?: string; - displayName?: string; - fullDisplayName?: string; // this includes the namespace name - kind?: string; - kindModifiers?: string; - triggerSpan?: TextSpan; - locations?: { - /** Note that the Text Spans are from bottom of file to top of file */ - [filePath: string]: TextSpan[] - }; -} -export function getRenameInfo(query: GetRenameInfoQuery): Promise { - consistentPath(query); - var project = getOrCreateProject(query.filePath); - var findInStrings = false, findInComments = false; - var info = project.languageService.getRenameInfo(query.filePath, query.position); - if (info && info.canRename) { - var locations: { [filePath: string]: TextSpan[] } = {}; - project.languageService.findRenameLocations(query.filePath, query.position, findInStrings, findInComments) - .forEach(loc=> { - if (!locations[loc.fileName]) locations[loc.fileName] = []; - - // Using unshift makes them with maximum value on top ;) - locations[loc.fileName].unshift(textSpan(loc.textSpan)); - }); - return resolve({ - canRename: true, - localizedErrorMessage: info.localizedErrorMessage, - displayName: info.displayName, - fullDisplayName: info.fullDisplayName, - kind: info.kind, - kindModifiers: info.kindModifiers, - triggerSpan: textSpan(info.triggerSpan), - locations: locations - }) - } - else { - return resolve({ - canRename: false - }); - } -} - -export interface GetIndentionAtPositionQuery extends FilePathPositionQuery { } -export interface GetIndentaionAtPositionResponse { - indent: number; -} -export function getIndentationAtPosition(query: GetIndentionAtPositionQuery): Promise { - consistentPath(query); - var project = getOrCreateProject(query.filePath); - var indent = project.languageService.getIndentationAtPosition(query.filePath, query.position, project.projectFile.project.formatCodeOptions); - - return resolve({ indent }); -} - -export interface DebugLanguageServiceHostVersionQuery extends FilePathQuery { } -export interface DebugLanguageServiceHostVersionResponse { text: string } -export function debugLanguageServiceHostVersion(query: DebugLanguageServiceHostVersionQuery): Promise { - consistentPath(query); - var project = getOrCreateProject(query.filePath); - return resolve({ text: project.languageServiceHost.getScriptContent(query.filePath) }); -} - -export interface GetProjectFileDetailsQuery extends FilePathQuery { } -export interface GetProjectFileDetailsResponse extends tsconfig.TypeScriptProjectFileDetails { } -export function getProjectFileDetails(query: GetProjectFileDetailsQuery): Promise { - consistentPath(query); - var project = getOrCreateProject(query.filePath); - return resolve(project.projectFile); -} - - -//-------------------------------------------------------------------------- -// getNavigationBarItems -//-------------------------------------------------------------------------- - -export interface GetNavigationBarItemsResponse { - items: NavigationBarItem[]; -} - -function sortNavbarItemsBySpan(items: ts.NavigationBarItem[]) { - items.sort((a, b) => a.spans[0].start - b.spans[0].start); - - // sort children recursively - for (let item of items) { - if (item.childItems) { - sortNavbarItemsBySpan(item.childItems); - } - } -} -/** - * Note the `indent` is fairly useless in ts service - * Basically only exists for global / module level and 0 elsewhere - * We make it true indent here ;) - */ -function flattenNavBarItems(items: ts.NavigationBarItem[]): ts.NavigationBarItem[] { - - var toreturn: ts.NavigationBarItem[] = []; - function keepAdding(item: ts.NavigationBarItem, depth: number) { - item.indent = depth; - var children = item.childItems; - delete item.childItems; - toreturn.push(item); - - if (children) { - children.forEach(child => keepAdding(child, depth + 1)); - } - } - // Kick it off - items.forEach(item => keepAdding(item, 0)); - - return toreturn; -} - -export function getNavigationBarItems(query: FilePathQuery): Promise { - consistentPath(query); - var project = getOrCreateProject(query.filePath); - var languageService = project.languageService; - var navBarItems = languageService.getNavigationBarItems(query.filePath); - - // remove the first global (whatever that is???) - if (navBarItems.length && navBarItems[0].text == "") { - navBarItems.shift(); - } - - // Sort items by first spans: - sortNavbarItemsBySpan(navBarItems); - - // And flatten - navBarItems = flattenNavBarItems(navBarItems); - - // Add a position - var items = navBarItems.map(item=> { - (item).position = project.languageServiceHost.getPositionFromIndex(query.filePath, item.spans[0].start); - delete item.spans; - return item; - }) - - return resolve({ items }); -} - -export interface SemanticTreeQuery extends FilePathQuery { } -export interface SemanticTreeReponse { - nodes: SemanticTreeNode[]; -} -function navigationBarItemToSemanticTreeNode(item: ts.NavigationBarItem, project: project.Project, query: FilePathQuery): SemanticTreeNode { - var toReturn: SemanticTreeNode = { - text: item.text, - kind: item.kind, - kindModifiers: item.kindModifiers, - start: project.languageServiceHost.getPositionFromIndex(query.filePath, item.spans[0].start), - end: project.languageServiceHost.getPositionFromIndex(query.filePath, item.spans[0].start + item.spans[0].length), - subNodes: item.childItems ? item.childItems.map(ci => navigationBarItemToSemanticTreeNode(ci, project, query)) : [] - } - return toReturn; -} -export function getSemtanticTree(query: SemanticTreeQuery): Promise { - consistentPath(query); - var project = getOrCreateProject(query.filePath); - - var navBarItems = project.languageService.getNavigationBarItems(query.filePath); - - // remove the first global (whatever that is???) - if (navBarItems.length && navBarItems[0].text == "") { - navBarItems.shift(); - } - - // Sort items by first spans: - sortNavbarItemsBySpan(navBarItems); - - // convert to SemanticTreeNodes - var nodes = navBarItems.map(nbi => navigationBarItemToSemanticTreeNode(nbi, project, query)); - - return resolve({ nodes }); -} - -//-------------------------------------------------------------------------- -// getNavigateToItems -//-------------------------------------------------------------------------- - -// Look at -// https://github.com/Microsoft/TypeScript/blob/master/src/services/navigateTo.ts -// for inspiration -// Reason for forking: -// didn't give all results -// gave results from lib.d.ts -// I wanted the practice - -export interface GetNavigateToItemsResponse { - items: NavigateToItem[]; -} -export function getNavigateToItems(query: FilePathQuery): Promise { - consistentPath(query); - var project = getOrCreateProject(query.filePath); - var languageService = project.languageService; - - let getNodeKind = ts.getNodeKind; - function getDeclarationName(declaration: ts.Declaration): string { - let result = getTextOfIdentifierOrLiteral(declaration.name); - if (result !== undefined) { - return result; - } - - if (declaration.name.kind === ts.SyntaxKind.ComputedPropertyName) { - let expr = (declaration.name).expression; - if (expr.kind === ts.SyntaxKind.PropertyAccessExpression) { - return (expr).name.text; - } - - return getTextOfIdentifierOrLiteral(expr); - } - - return undefined; - } - function getTextOfIdentifierOrLiteral(node: ts.Node) { - if (node.kind === ts.SyntaxKind.Identifier || - node.kind === ts.SyntaxKind.StringLiteral || - node.kind === ts.SyntaxKind.NumericLiteral) { - - return ( node).text; - } - - return undefined; - } - - var items: NavigateToItem[] = []; - for (let file of project.getProjectSourceFiles()) { - let declarations = file.getNamedDeclarations(); - for (let index in declarations) { - for (let declaration of declarations[index]) { - let item: NavigateToItem = { - name: getDeclarationName(declaration), - kind: getNodeKind(declaration), - filePath: file.fileName, - fileName: path.basename(file.fileName), - position: project.languageServiceHost.getPositionFromIndex(file.fileName, declaration.getStart()) - } - items.push(item); - } - } - } - - return resolve({ items }); -} - -//-------------------------------------------------------------------------- -// getReferences -//-------------------------------------------------------------------------- -export interface GetReferencesQuery extends FilePathPositionQuery { } -export interface GetReferencesResponse { - references: ReferenceDetails[]; -} -export function getReferences(query: GetReferencesQuery): Promise { - consistentPath(query); - var project = getOrCreateProject(query.filePath); - var languageService = project.languageService; - - var references: ReferenceDetails[] = []; - var refs = languageService.getReferencesAtPosition(query.filePath, query.position) || []; - - references = refs.map(r=> { - var res = project.languageServiceHost.getPositionFromTextSpanWithLinePreview(r.fileName, r.textSpan); - return { filePath: r.fileName, position: res.position, preview: res.preview } - }); - - return resolve({ - references - }) -} - -/** - * Get Completions for external modules + references tags - */ -import {getPathCompletions, GetRelativePathsInProjectResponse } -from "./modules/getPathCompletions"; - -function filePathWithoutExtension(query: string) { - var base = path.basename(query, '.ts'); - return path.dirname(query) + '/' + base; -} -interface GetRelativePathsInProjectQuery { - filePath: string; - prefix: string; - includeExternalModules: boolean; -} - -export function getRelativePathsInProject(query: GetRelativePathsInProjectQuery): Promise { - consistentPath(query); - var project = getOrCreateProject(query.filePath); - return resolve(getPathCompletions({ - project, - filePath: query.filePath, - prefix: query.prefix, - includeExternalModules: query.includeExternalModules - })); -} - -/** - * Get AST - */ -import {astToText, astToTextFull} from "./modules/astToText"; -export interface GetASTQuery extends FilePathQuery { } -export interface GetASTResponse { - root?: NodeDisplay -} -export function getAST(query: GetASTQuery): Promise { - consistentPath(query); - var project = getOrCreateProject(query.filePath); - var service = project.languageService; - - var files = service.getProgram().getSourceFiles().filter(x=> x.fileName == query.filePath); - if (!files.length) resolve({}); - - var sourceFile = files[0]; - - var root = astToText(sourceFile); - - return resolve({ root }); -} - -export interface GetASTFullQuery extends FilePathQuery { } -export interface GetASTFullResponse { - root?: NodeDisplay -} -export function getASTFull(query: GetASTQuery): Promise { - consistentPath(query); - var project = getOrCreateProject(query.filePath); - var service = project.languageService; - - var files = service.getProgram().getSourceFiles().filter(x=> x.fileName == query.filePath); - if (!files.length) resolve({}); - - var sourceFile = files[0]; - - var root = astToTextFull(sourceFile); - - return resolve({ root }); -} - -/** - * Get Dependencies - */ -import programDependencies from "./modules/programDependencies"; -export interface GetDependenciesQuery extends FilePathQuery { } -export interface GetDependenciesResponse { - links: FileDependency[] -} -export function getDependencies(query: GetDependenciesQuery): Promise { - consistentPath(query); - var project = getOrCreateProject(query.filePath); - - var projectFile = project.projectFile; - var links = programDependencies(projectFile, project.languageService.getProgram()); - - return resolve({ links }); -} - -/** - * Get Quick Fix - */ -import {QuickFix, QuickFixQueryInformation, Refactoring} from "./fixmyts/quickFix"; -import * as qf from "./fixmyts/quickFix"; -import * as ast from "./fixmyts/astUtils"; -import {allQuickFixes} from "./fixmyts/quickFixRegistry"; -function getInfoForQuickFixAnalysis(query: FilePathPositionQuery): QuickFixQueryInformation { - consistentPath(query); - let project = getOrCreateProject(query.filePath); - let program = project.languageService.getProgram(); - let sourceFile = program.getSourceFile(query.filePath); - let sourceFileText: string, - fileErrors: ts.Diagnostic[], - positionErrors: ts.Diagnostic[], - positionErrorMessages: string[], - positionNode: ts.Node; - if (project.includesSourceFile(query.filePath)) { - sourceFileText = sourceFile.getFullText(); - fileErrors = getDiagnositcsByFilePath(query); - /** We want errors that are *touching* and thefore expand the query position by one */ - positionErrors = fileErrors.filter(e=> ((e.start - 1) < query.position) && (e.start + e.length + 1) > query.position); - positionErrorMessages = positionErrors.map(e=> ts.flattenDiagnosticMessageText(e.messageText, os.EOL)); - positionNode = ts.getTokenAtPosition(sourceFile, query.position); - } else { - sourceFileText = ""; - fileErrors = []; - positionErrors = []; - positionErrorMessages = []; - positionNode = undefined; - } - - let service = project.languageService; - let typeChecker = program.getTypeChecker(); - - return { - project, - program, - sourceFile, - sourceFileText, - fileErrors, - positionErrors, - positionErrorMessages, - position: query.position, - positionNode, - service, - typeChecker, - filePath: query.filePath - }; -} - -export interface GetQuickFixesQuery extends FilePathPositionQuery { } -export interface QuickFixDisplay { - /** Uniquely identifies which function will be called to carry out the fix */ - key: string; - /** What will be displayed in the UI */ - display: string; - /** Does this quickfix provide a snippet */ - isNewTextSnippet: boolean; -} -export interface GetQuickFixesResponse { - fixes: QuickFixDisplay[]; -} -export function getQuickFixes(query: GetQuickFixesQuery): Promise { - consistentPath(query); - var project = getOrCreateProject(query.filePath); - - if (!project.includesSourceFile(query.filePath)) { - return resolve({ fixes: [] }); - } - - var info = getInfoForQuickFixAnalysis(query); - - // And then we let the quickFix determine if it wants provide any fixes for this file - // And if so we also treat the result as a display string - var fixes = allQuickFixes - .map(x => { - var canProvide = x.canProvideFix(info); - if (!canProvide) - return; - else - return { key: x.key, display: canProvide.display, isNewTextSnippet: canProvide.isNewTextSnippet }; - }) - .filter(x=> !!x); - - return resolve({ fixes }); -} - -export interface ApplyQuickFixQuery extends FilePathPositionQuery { - key: string; - - // This will need to be special cased - additionalData?: any; -} -export interface ApplyQuickFixResponse { - refactorings: qf.RefactoringsByFilePath; -} -export function applyQuickFix(query: ApplyQuickFixQuery): Promise { - consistentPath(query); - - var fix = allQuickFixes.filter(x=> x.key == query.key)[0]; - var info = getInfoForQuickFixAnalysis(query); - var res = fix.provideFix(info); - var refactorings = qf.getRefactoringsByFilePath(res); - return resolve({ refactorings }); -} - - -/** - * Get Output for possible use elsewhere - */ -interface GetOutputResponse { - output: ts.EmitOutput; -} -import {getRawOutput} from "./modules/building"; -export function getOutput(query: FilePathQuery): Promise { - consistentPath(query); - var project = getOrCreateProject(query.filePath); - return resolve({ output: getRawOutput(project, query.filePath) }); -} -interface GetOutputJsResponse { - jsFilePath?: string; -} -export function getOutputJs(query: FilePathQuery): Promise { - consistentPath(query); - - var project = getOrCreateProject(query.filePath); - var output = getRawOutput(project, query.filePath); - var jsFile = output.outputFiles.filter(x=> path.extname(x.name) == ".js" || path.extname(x.name) == ".jsx")[0]; - - if (!jsFile || output.emitSkipped) { - return resolve({}); - } else { - return resolve({ jsFilePath: jsFile.name }); - } -} -interface GetOutputJsStatusResponse { - /** true if *no emit* or *emit is as desired* */ - emitDiffers: boolean; -} -export function getOutputJsStatus(query: FilePathQuery): Promise { - consistentPath(query); - var project = getOrCreateProject(query.filePath); - var output = getRawOutput(project, query.filePath); - if (output.emitSkipped) { - if (output.outputFiles && output.outputFiles.length === 1) { - if (output.outputFiles[0].text === building.Not_In_Context) { - return resolve({ emitDiffers: false }); - } - } - return resolve({ emitDiffers: true }); - } - var jsFile = output.outputFiles.filter(x=> path.extname(x.name) == ".js")[0]; - if (!jsFile) { - return resolve({ emitDiffers: false }); - } else { - var emitDiffers = !fs.existsSync(jsFile.name) || fs.readFileSync(jsFile.name).toString() !== jsFile.text; - return resolve({ emitDiffers }); - } -} - -/** - * Reset all that we know about the file system - */ -export function softReset(query: SoftResetQuery): Promise<{}> { - resetCache(query); - return resolve({}); -} - -/** - * Get rename files refactorings - */ -import * as moveFiles from "./modules/moveFiles"; -export interface GetRenameFilesRefactoringsQuery { - oldPath: string; - newPath: string; -} -export function getRenameFilesRefactorings(query: GetRenameFilesRefactoringsQuery): Promise { - query.oldPath = fsu.consistentPath(query.oldPath); - query.newPath = fsu.consistentPath(query.newPath); - var project = getOrCreateProject(query.oldPath); - var res = moveFiles.getRenameFilesRefactorings(project.languageService.getProgram(), query.oldPath, query.newPath); - var refactorings = qf.getRefactoringsByFilePath(res); - return resolve({ refactorings }); -} - -export interface CreateProjectQuery extends FilePathQuery { } -export interface CreateProjectResponse { - createdFilePath: string; -} -export function createProject(query: CreateProjectQuery): Promise { - consistentPath(query); - var projectFile = tsconfig.createProjectRootSync(query.filePath); - queryParent.setConfigurationError({ projectFilePath: query.filePath, error: null }); - return resolve({ createdFilePath: projectFile.projectFilePath }); -} - -/** - * Toggle breakpoint - */ -export interface ToggleBreakpointQuery extends FilePathPositionQuery { } -export interface ToggleBreakpointResponse { - refactorings: qf.RefactoringsByFilePath; -} -export function toggleBreakpoint(query: ToggleBreakpointQuery): Promise { - consistentPath(query); - var project = getOrCreateProject(query.filePath); - - // Get the node at the current location. - let program = project.languageService.getProgram(); - let sourceFile = program.getSourceFile(query.filePath); - let sourceFileText = sourceFile.getFullText(); - let positionNode = ts.getTokenAtPosition(sourceFile, query.position); - - let refactoring: Refactoring; - - // Because we add a debugger *before* the current token - // ... just preemptively check the previous token to see if *that* is a debugger keyword by any chance - if (positionNode.kind != ts.SyntaxKind.DebuggerKeyword && positionNode.getFullStart() > 0) { - let previousNode = ts.getTokenAtPosition(sourceFile, positionNode.getFullStart() - 1); - // Note: the previous node might be `debugger` - if (previousNode.kind == ts.SyntaxKind.DebuggerStatement) { - positionNode = previousNode; - } - // Or `debugger;` (previous node would be `;` but parent is the right one) - if (previousNode.parent && previousNode.parent.kind == ts.SyntaxKind.DebuggerStatement) { - positionNode = previousNode.parent; - } - } - - // If it is a debugger keyword ... remove it - if (positionNode.kind == ts.SyntaxKind.DebuggerKeyword || positionNode.kind == ts.SyntaxKind.DebuggerStatement) { - let start = positionNode.getFullStart(); - let end = start + positionNode.getFullWidth(); - - // also get trailing semicolons - while (end < sourceFileText.length && sourceFileText[end] == ';') { - end = end + 1; - } - - refactoring = { - filePath: query.filePath, - span: { - start: start, - length: end - start - }, - newText: '' - } - } - // Otherwise add a breakpoint; *before* the current token whatever that may be - else { - let toInsert = 'debugger;'; - refactoring = { - filePath: query.filePath, - span: { - start: positionNode.getFullStart(), - length: 0 - }, - newText: toInsert - } - } - - var refactorings = qf.getRefactoringsByFilePath(refactoring ? [refactoring] : []); - return resolve({ refactorings }); -} diff --git a/lib/main/lang/transformers/implementations/nullTransformer.ts b/lib/main/lang/transformers/implementations/nullTransformer.ts deleted file mode 100644 index 68b7edb9e..000000000 --- a/lib/main/lang/transformers/implementations/nullTransformer.ts +++ /dev/null @@ -1,12 +0,0 @@ -import {Transformer} from "../transformer"; -import {add} from "../transformerRegistry"; - -/** Does no transform whatsoever. This is to test the infrastructure */ -export class NullTransformer implements Transformer { - name = "null"; - - transform(code: string) { - return { code }; - } -} -add(new NullTransformer()); \ No newline at end of file diff --git a/lib/main/lang/transformers/transformer.ts b/lib/main/lang/transformers/transformer.ts deleted file mode 100644 index a0328032d..000000000 --- a/lib/main/lang/transformers/transformer.ts +++ /dev/null @@ -1,101 +0,0 @@ -import * as path from "path"; -import * as sourceMap from "source-map"; - -export interface TransformResult { - code: string; - /** Source map */ - map?: sourceMap.SourceMapGenerator; -} - -/** Must be implemented by a transformer */ -export interface Transformer { - /** The name we register by */ - name: string; - - transform(code: string): { code: string; }; - - /** Stuff we will provide for you - * So you don't need to *implement* it explicitly - */ - regex?: RegExp; -} - -export interface FileTransformationDetails { - transforms: TransformerDelimiter[]; -} - -export interface TransformerDelimiter { - /** .tst file */ - srcMinChar: number; - srcLimChar: number; - - /** .tst.ts file */ - destMinChar: number; - destLimChar: number; - - /** which transformer did this */ - transformer: Transformer; -} - -export interface AtomTSTokens { tokens: any /* Atom's Token */[]; ruleStack: any[] } - -/** Is this file something that needs to be transformed */ -export function isTransformerFile(filePath: string) { - var ext = path.extname(filePath); - return ext == '.tst'; -} - -/** - * If this is a file that needs to be transformed ... - * then returns the path of the pseudo ts file - * else returns filePath as is - */ -export function getPseudoFilePath(filePath: string) { - if (isTransformerFile(filePath)) { - return getPseudoTsFile(filePath); - } - return filePath; -} - -function getPseudoTsFile(filePath: string) { - return filePath + '.ts'; -} - -/** - * Reliably get a file that will be on the file system - * If the file is a pseudo file - * , then return the .tst file - * otherwise just return the filePath as is - */ -export function getTransformerFile(filePath: string) { - if (endsWith(filePath, '.tst.ts')) { - filePath = removeExt(filePath); - } - return filePath; -} - -/** - * A raw file is something that we create in memory stripping out - * any transform locations to get the TS language service - * to parse the file out for us for free. - * This allows us to create fancier transformers that can use the surrounding AST / typechecker - */ -export function isRawFile(filePath: string) { - return endsWith(filePath, ".raw.ts"); -} - -/** - * We transform the `.tst` file into a `.tst.ts` file in memory and feed it to the language service - */ -export function isPseudoFile(filePath: string) { - var ext = path.extname(filePath); - return endsWith(filePath, ".tst.ts"); -} - -function endsWith(str: string, suffix: string): boolean { - return str && str.indexOf(suffix, str.length - suffix.length) !== -1; -} - -function removeExt(filePath: string) { - return filePath && filePath.substr(0, filePath.lastIndexOf('.')); -} diff --git a/lib/main/lang/transformers/transformerRegistry.ts b/lib/main/lang/transformers/transformerRegistry.ts deleted file mode 100644 index f4cc21c46..000000000 --- a/lib/main/lang/transformers/transformerRegistry.ts +++ /dev/null @@ -1,80 +0,0 @@ -import utils = require("../utils"); -import {Transformer, TransformerDelimiter, FileTransformationDetails} from "./transformer"; - -/** - * Transformers should push themeselves into this registry. - * This is so that the registry does not depend on the transformers - * As that will cause a circular reference - */ -var allTransformers: Transformer[] = [ -]; - -export function add(transformer: Transformer) { - transformer.regex = (new RegExp(`transform:${transformer.name}{[.\\s]*}transform:${transformer.name}`, 'g')); - allTransformers.push(transformer); -} - -/** Returns the name of the added transformers */ -export function getNames() { - return allTransformers.map(at=> at.name); -} - -/** Returns the regexes for all the added transformers */ -export function getRegexes() { - return allTransformers.map(at=> at.regex); -} - -var transformFinderRegex = /transform:(.*){/g -var transformEndFinderRegexGenerator = (name: string) => new RegExp(`}transform:${name}`); -export function getInitialTransformation(code: string): FileTransformationDetails { - - - var transforms: TransformerDelimiter[] = []; - // var processedSrcUpto = 0; - // var srcCode = code; - // var destCode = ''; - // var destDelta = 0; - // - // while (true) { - // let remainingCode = code.substr(processedSrcUpto); - // // Get the next transform that exist in this file: - // var matches = transformFinderRegex.exec(remainingCode); - // // No more transforms: - // if (!matches || !matches.length || matches.length < 2) return { transforms }; - // // Found one! - // var nextTransformName = matches.slice[1]; - // // Update the processedUpto - // break; - // } - // - // /** - // * TODO: for each transform we note down the src start and src end - // * Then we transform the src code. This gives a dest start (initially same as src start) and dest end (more or less) - // * we use this to additionally compute a running (delta) in dest. This delta is used in the next (dest start). - // */ - - - return { transforms }; -} - -export function transform(name: string, code: string): { code: string } { - var transformer = allTransformers.filter(at => at.name == name)[0]; - - if (!transformer) { - console.error('No transformer registered with name: ', name); - return { code: '' }; - } - - return transformer.transform(code); -} - -// Ensure that all the transformers are loaded: -// Since nothing depends on these explicitly (don't want a circular ref) -// We need to load them manually: -import * as path from "path"; -var glob = require('glob'); -let files: string[] = glob.sync('./implementations/*.js', { - nodir: true, - cwd: __dirname -}); -files = files.map(f=> require(f)); diff --git a/lib/main/lang/typescriptServices.ts b/lib/main/lang/typescriptServices.ts deleted file mode 100644 index 58d7c7b64..000000000 --- a/lib/main/lang/typescriptServices.ts +++ /dev/null @@ -1,5 +0,0 @@ -export var typescriptServices = ''; - -export function setTypescriptServices(path: string) { - typescriptServices = path; -} diff --git a/lib/main/lang/utils.ts b/lib/main/lang/utils.ts index a5cdbd763..5a182db34 100644 --- a/lib/main/lang/utils.ts +++ b/lib/main/lang/utils.ts @@ -104,199 +104,6 @@ export interface ISignal { hasListeners(): boolean; } - -export class Signal implements ISignal { - - /** - * list of listeners that have been suscribed to this signal - */ - private listeners: { (parameter: T): any }[] = []; - - /** - * Priorities corresponding to the listeners - */ - private priorities: number[] = []; - - /** - * Subscribes a listener for the signal. - * - * @params listener the callback to call when events are dispatched - * @params priority an optional priority for this signal - */ - add(listener: (parameter: T) => any, priority = 0): void { - var index = this.listeners.indexOf(listener); - if (index !== -1) { - this.priorities[index] = priority; - return; - } - for (var i = 0, l = this.priorities.length; i < l; i++) { - if (this.priorities[i] < priority) { - this.priorities.splice(i, 0, priority); - this.listeners.splice(i, 0, listener); - return; - } - } - this.priorities.push(priority); - this.listeners.push(listener); - } - - /** - * unsubscribe a listener for the signal - * - * @params listener the previously subscribed listener - */ - remove(listener: (parameter: T) => any): void { - var index = this.listeners.indexOf(listener); - if (index >= 0) { - this.priorities.splice(index, 1); - this.listeners.splice(index, 1); - } - } - - /** - * dispatch an event - * - * @params parameter the parameter attached to the event dispatching - */ - dispatch(parameter?: T): boolean { - var hasBeenCanceled = this.listeners.every((listener: (parameter: T) => any) => { - var result = listener(parameter); - return result !== false; - }); - - return hasBeenCanceled; - } - - /** - * Remove all listener from the signal - */ - clear(): void { - this.listeners = []; - this.priorities = []; - } - - /** - * @return true if the listener has been subsribed to this signal - */ - hasListeners(): boolean { - return this.listeners.length > 0; - } -} - -export function binarySearch(array: number[], value: number): number { - var low = 0; - var high = array.length - 1; - - while (low <= high) { - var middle = low + ((high - low) >> 1); - var midValue = array[middle]; - - if (midValue === value) { - return middle; - } - else if (midValue > value) { - high = middle - 1; - } - else { - low = middle + 1; - } - } - - return ~low; -} - -// Not optimized -export function selectMany(arr: T[][]): T[] { - var result = []; - for (var i = 0; i < arr.length; i++) { - for (var j = 0; j < arr[i].length; j++) { - result.push(arr[i][j]); - } - } - return result; -} - -// Not particularly awesome e.g. '/..foo' will pass -export function pathIsRelative(str: string) { - if (!str.length) return false; - return str[0] == '.' || str.substring(0, 2) == "./" || str.substring(0, 3) == "../"; -} - -/** Key is string. Note: this data structure might have been a bad idea. Sorry. */ -export class Dict{ - public table = Object.create(null); - constructor() { } - setValue(key: string, item: T) { - this.table[key] = item; - } - getValue(key: string) { return this.table[key]; } - clearValue(key: string) { - delete this.table[key]; - } - clearAll() { this.table = Object.create(null); } - keys() { return Object.keys(this.table); } - values(): T[] { - var array = []; - for (var key in this.table) { - array.push(this.table[key]); - } - return array; - } -} - -/** for testing ui lags only */ -export function delay(seconds: number = 2) { - delayMilliseconds(seconds * 1000); -}; - -export function delayMilliseconds(milliseconds: number = 100) { - // Delay the thread - var d1 = new Date(); - var d2 = new Date(); - while (d2.valueOf() < d1.valueOf() + milliseconds) { - d2 = new Date(); - } -}; - -var now = () => new Date().getTime(); - -export function debounce(func: T, milliseconds: number, immediate = false): T { - var timeout, args, context, timestamp, result; - - var wait = milliseconds; - - var later = function() { - var last = now() - timestamp; - - if (last < wait && last > 0) { - timeout = setTimeout(later, wait - last); - } else { - timeout = null; - if (!immediate) { - result = func.apply(context, args); - if (!timeout) context = args = null; - } - } - }; - - return function() { - context = this; - args = arguments; - timestamp = now(); - var callNow = immediate && !timeout; - if (!timeout) timeout = setTimeout(later, wait); - if (callNow) { - result = func.apply(context, args); - context = args = null; - } - - return result; - }; -}; - -var punctuations = createMap([';', '{', '}', '(', ')', '.', ':', '<', '>', "'", '"']); -export var prefixEndsInPunctuation = (prefix) => prefix.length && prefix.trim().length && punctuations[prefix.trim()[prefix.trim().length - 1]]; - var nameExtractorRegex = /return (.*);/; /** Get the name using a lambda so that you don't have magic strings */ export function getName(nameLambda: () => any) { @@ -311,4 +118,4 @@ export function getName(nameLambda: () => any) { export function distinct(arr: string[]): string[] { var map = createMap(arr); return Object.keys(map); -} \ No newline at end of file +} diff --git a/lib/main/react/htmltotsx.ts b/lib/main/react/htmltotsx.ts deleted file mode 100644 index 89bc8c869..000000000 --- a/lib/main/react/htmltotsx.ts +++ /dev/null @@ -1,13 +0,0 @@ -/** - * Take a look at : - * https://github.com/reactjs/react-magic - * https://www.npmjs.com/package/htmltojsx - */ - -import HTMLtoJSX = require("htmltojsx"); -export function convert(content: string, indentSize: number) { - var indent = Array(indentSize + 1).join(' '); - var converter = new HTMLtoJSX({ indent: indent, createClass: false }); - var output = converter.convert(content); - return output; -} diff --git a/lib/main/tsconfig/dts-generator.ts b/lib/main/tsconfig/dts-generator.ts deleted file mode 100644 index 7ef8fb2bc..000000000 --- a/lib/main/tsconfig/dts-generator.ts +++ /dev/null @@ -1,237 +0,0 @@ -/** - * All rights : https://github.com/SitePen/dts-generator - * I needed to rework it to work with package.json + tsconfig.json - */ - -import pathUtil = require("path"); -import os = require("os"); -import fs = require("fs"); -import mkdirp = require("mkdirp"); - -interface Options { - baseDir: string; - files: string[]; - excludes?: string[]; - externs?: string[]; - eol?: string; - includes?: string[]; - indent?: string; - main?: string; - name: string; - out: string; - target?: ts.ScriptTarget; - outDir?: string; -} - -function consistentPath(filePath: string): string { - return filePath.split('\\').join('/'); -} - -function getError(diagnostics: ts.Diagnostic[]) { - var message = 'Declaration generation failed'; - - diagnostics.forEach(function(diagnostic) { - var position = diagnostic.file.getLineAndCharacterOfPosition(diagnostic.start); - - message += - `\n${diagnostic.file.fileName}(${position.line + 1},${position.character + 1}): ` + - `error TS${diagnostic.code}: ${diagnostic.messageText}`; - }); - - var error = new Error(message); - error.name = 'EmitterError'; - return error; -} - -// Converts "C:\boo" , "C:\boo\foo.ts" => "./foo.ts"; Works on unix as well. -function makeRelativePath(relativeFolder: string, filePath: string) { - var relativePath = pathUtil.relative(relativeFolder, filePath).split('\\').join('/'); - if (relativePath[0] !== '.') { - relativePath = './' + relativePath; - } - return relativePath; -} - -function getFilenames(baseDir: string, files: string[]): string[] { - return files.map(function(filename) { - var resolvedFilename = pathUtil.resolve(filename); - if (resolvedFilename.indexOf(baseDir) === 0) { - return resolvedFilename; - } - - return pathUtil.resolve(baseDir, filename); - }); -} - -function processTree(sourceFile: ts.SourceFile, replacer: (node: ts.Node) => string): string { - var code = ''; - var cursorPosition = 0; - - function skip(node: ts.Node) { - cursorPosition = node.end; - } - - function readThrough(node: ts.Node) { - code += sourceFile.text.slice(cursorPosition, node.pos); - cursorPosition = node.pos; - } - - function visit(node: ts.Node) { - readThrough(node); - - var replacement = replacer(node); - - if (replacement != null) { - code += replacement; - skip(node); - } - else { - ts.forEachChild(node, visit); - } - } - - visit(sourceFile); - code += sourceFile.text.slice(cursorPosition); - - return code; -} - -export function generate(options: Options, sendMessage: (message: string) => void = function() { }) { - var baseDir = pathUtil.resolve(options.baseDir); - var eol = options.eol || os.EOL; - var nonEmptyLineStart = new RegExp(eol + '(?!' + eol + '|$)', 'g'); - var indent = options.indent === undefined ? '\t' : options.indent; - var target = options.target || ts.ScriptTarget.Latest; - var compilerOptions: ts.CompilerOptions = { - declaration: true, - module: ts.ModuleKind.CommonJS, - target: target - }; - - if (options.outDir) { - compilerOptions.outDir = options.outDir - } - - var filenames = getFilenames(baseDir, options.files); - var excludesMap: { [filename: string]: boolean; } = {}; - options.excludes && options.excludes.forEach(function(filename) { - excludesMap[consistentPath(pathUtil.resolve(baseDir, filename))] = true; - }); - var externsMap: { [filename: string]: boolean; } = {}; - options.externs && options.externs.forEach(function(filename) { - externsMap[consistentPath(pathUtil.resolve(baseDir, filename))] = true; - }); - - mkdirp.sync(pathUtil.dirname(options.out)); - var output = fs.createWriteStream(options.out, { mode: parseInt('644', 8) }); - - var host = ts.createCompilerHost(compilerOptions); - var program = ts.createProgram(filenames, compilerOptions, host); - var checker = ts.createTypeChecker(program, true); - - function writeFile(filename: string, data: string, writeByteOrderMark: boolean) { - // Compiler is emitting the non-declaration file, which we do not care about - if (filename.slice(-5) !== '.d.ts') { - return; - } - - writeDeclaration(ts.createSourceFile(filename, data, target, true)); - } - - return new Promise(function(resolve, reject) { - output.on('close', () => { resolve(undefined); }); - output.on('error', reject); - - if (options.externs) { - let relativeRoot = pathUtil.dirname(options.out); - options.externs.forEach(function(path: string) { - sendMessage(`Writing external dependency ${path}`); - output.write(`/// ${eol}`); - }); - } - - program.getSourceFiles().some(function(sourceFile) { - // Source file is a default library, or other dependency from another project, that should not be included in - // our bundled output - if (pathUtil.normalize(sourceFile.fileName).indexOf(baseDir) !== 0) { - return; - } - - if (excludesMap[sourceFile.fileName]) { - return; - } - - if (externsMap[sourceFile.fileName]) { - return; - } - - sendMessage(`Processing ${sourceFile.fileName}`); - - // Source file is already a declaration file so should does not need to be pre-processed by the emitter - if (sourceFile.fileName.slice(-5) === '.d.ts') { - writeDeclaration(sourceFile); - return; - } - - var emitOutput = program.emit(sourceFile, writeFile); - if (emitOutput.emitSkipped) { - reject(getError( - emitOutput.diagnostics - .concat(program.getSemanticDiagnostics(sourceFile)) - .concat(program.getSyntacticDiagnostics(sourceFile)) - .concat(program.getDeclarationDiagnostics(sourceFile)) - )); - - return true; - } - }); - - if (options.main) { - output.write(`declare module '${options.name}' {` + eol + indent); - output.write(`import main = require('${options.main}');` + eol + indent); - output.write('export = main;' + eol); - output.write('}' + eol); - sendMessage(`Aliased main module ${options.name} to ${options.main}`); - } - - output.end(); - }); - - function writeDeclaration(declarationFile: ts.SourceFile) { - var filename = declarationFile.fileName; - var sourceModuleId = options.name + consistentPath(filename.slice(baseDir.length, -5)); - - if (declarationFile.externalModuleIndicator) { - output.write('declare module \'' + sourceModuleId + '\' {' + eol + indent); - - var content = processTree(declarationFile, function(node) { - if (node.kind === ts.SyntaxKind.ExternalModuleReference) { - var expression = ( node).expression; - - if (expression.text.charAt(0) === '.') { - return ' require(\'' + pathUtil.join(pathUtil.dirname(sourceModuleId), expression.text) + '\')'; - } - } - else if (node.kind === ts.SyntaxKind.DeclareKeyword) { - return ''; - } - else if ( - node.kind === ts.SyntaxKind.StringLiteral && - (node.parent.kind === ts.SyntaxKind.ExportDeclaration - || node.parent.kind === ts.SyntaxKind.ImportDeclaration) - ) { - var text = (node).text; - if (text.charAt(0) === '.') { - return ` '${consistentPath(pathUtil.join(pathUtil.dirname(sourceModuleId), text)) }'`; - } - } - }); - - output.write(content.replace(nonEmptyLineStart, '$&' + indent)); - output.write(eol + '}' + eol); - } - else { - output.write(declarationFile.text); - } - } -} \ No newline at end of file diff --git a/lib/main/tsconfig/formatting.ts b/lib/main/tsconfig/formatting.ts index 6192b9452..76e30eb25 100644 --- a/lib/main/tsconfig/formatting.ts +++ b/lib/main/tsconfig/formatting.ts @@ -5,96 +5,27 @@ * - the defaultFormatCodeOptions function * - the makeFormatCodeOptions function */ +import {EOL} from "os" +import * as protocol from "typescript/lib/protocol" -import os = require('os'); - -/// The following two interfaces come from typescript.d.ts but camelCased for JSON parsing -interface EditorOptions { - indentSize: number; - tabSize: number; - newLineCharacter: string; - convertTabsToSpaces: boolean; -} -export interface FormatCodeOptions extends EditorOptions { - insertSpaceAfterCommaDelimiter: boolean; - insertSpaceAfterSemicolonInForStatements: boolean; - insertSpaceBeforeAndAfterBinaryOperators: boolean; - insertSpaceAfterKeywordsInControlFlowStatements: boolean; - insertSpaceAfterFunctionKeywordForAnonymousFunctions: boolean; - insertSpaceAfterOpeningAndBeforeClosingNonemptyParenthesis: boolean; - insertSpaceAfterOpeningAndBeforeClosingNonemptyBrackets: boolean; - insertSpaceAfterOpeningAndBeforeClosingTemplateStringBraces: boolean; - placeOpenBraceOnNewLineForFunctions: boolean; - placeOpenBraceOnNewLineForControlBlocks: boolean; -} - -export function defaultFormatCodeOptions(): ts.FormatCodeOptions { +export function defaultFormatCodeOptions(): protocol.FormatCodeSettings { return { - IndentSize: 4, - TabSize: 4, - NewLineCharacter: os.EOL, - ConvertTabsToSpaces: true, - IndentStyle: ts.IndentStyle.Smart, - InsertSpaceAfterCommaDelimiter: true, - InsertSpaceAfterSemicolonInForStatements: true, - InsertSpaceBeforeAndAfterBinaryOperators: true, - InsertSpaceAfterKeywordsInControlFlowStatements: true, - InsertSpaceAfterFunctionKeywordForAnonymousFunctions: false, - InsertSpaceAfterOpeningAndBeforeClosingNonemptyParenthesis: false, - InsertSpaceAfterOpeningAndBeforeClosingNonemptyBrackets: false, - InsertSpaceAfterOpeningAndBeforeClosingTemplateStringBraces: false, - PlaceOpenBraceOnNewLineForFunctions: false, - PlaceOpenBraceOnNewLineForControlBlocks: false, + baseIndentSize: 4, + indentSize: 4, + tabSize: 4, + newLineCharacter: EOL, + convertTabsToSpaces: true, + indentStyle: "Smart", + insertSpaceAfterCommaDelimiter: true, + insertSpaceAfterSemicolonInForStatements: true, + insertSpaceBeforeAndAfterBinaryOperators: true, + insertSpaceAfterKeywordsInControlFlowStatements: true, + insertSpaceAfterFunctionKeywordForAnonymousFunctions: false, + insertSpaceAfterOpeningAndBeforeClosingNonemptyParenthesis: false, + insertSpaceAfterOpeningAndBeforeClosingNonemptyBrackets: false, + insertSpaceAfterOpeningAndBeforeClosingTemplateStringBraces: false, + insertSpaceAfterOpeningAndBeforeClosingJsxExpressionBraces: false, + placeOpenBraceOnNewLineForFunctions: false, + placeOpenBraceOnNewLineForControlBlocks: false, }; -} - -export function makeFormatCodeOptions(config: FormatCodeOptions): ts.FormatCodeOptions { - var options = defaultFormatCodeOptions(); - if (!config) { - return options; - } - if (typeof config.insertSpaceAfterCommaDelimiter === "boolean") { - options.InsertSpaceAfterCommaDelimiter = config.insertSpaceAfterCommaDelimiter; - } - if (typeof config.insertSpaceAfterSemicolonInForStatements === "boolean") { - options.InsertSpaceAfterSemicolonInForStatements = config.insertSpaceAfterSemicolonInForStatements; - } - if (typeof config.insertSpaceBeforeAndAfterBinaryOperators === "boolean") { - options.InsertSpaceBeforeAndAfterBinaryOperators = config.insertSpaceBeforeAndAfterBinaryOperators; - } - if (typeof config.insertSpaceAfterKeywordsInControlFlowStatements === "boolean") { - options.InsertSpaceAfterKeywordsInControlFlowStatements = config.insertSpaceAfterKeywordsInControlFlowStatements; - } - if (typeof config.insertSpaceAfterFunctionKeywordForAnonymousFunctions === "boolean") { - options.InsertSpaceAfterFunctionKeywordForAnonymousFunctions = config.insertSpaceAfterFunctionKeywordForAnonymousFunctions; - } - if (typeof config.insertSpaceAfterOpeningAndBeforeClosingNonemptyParenthesis === "boolean") { - options.InsertSpaceAfterOpeningAndBeforeClosingNonemptyParenthesis = config.insertSpaceAfterOpeningAndBeforeClosingNonemptyParenthesis; - } - if (typeof config.insertSpaceAfterOpeningAndBeforeClosingNonemptyBrackets === "boolean") { - options.InsertSpaceAfterOpeningAndBeforeClosingNonemptyBrackets = config.insertSpaceAfterOpeningAndBeforeClosingNonemptyBrackets; - } - if (typeof config.insertSpaceAfterOpeningAndBeforeClosingTemplateStringBraces === "boolean") { - options.InsertSpaceAfterOpeningAndBeforeClosingTemplateStringBraces = config.insertSpaceAfterOpeningAndBeforeClosingTemplateStringBraces; - } - if (typeof config.placeOpenBraceOnNewLineForFunctions === "boolean") { - options.PlaceOpenBraceOnNewLineForFunctions = config.placeOpenBraceOnNewLineForFunctions; - } - if (typeof config.placeOpenBraceOnNewLineForControlBlocks === "boolean") { - options.PlaceOpenBraceOnNewLineForControlBlocks = config.placeOpenBraceOnNewLineForControlBlocks; - } - if (typeof config.indentSize === "number") { - options.IndentSize = config.indentSize; - } - if (typeof config.tabSize === "number") { - options.TabSize = config.tabSize; - } - if (typeof config.newLineCharacter === "string") { - options.NewLineCharacter = config.newLineCharacter; - } - if (typeof config.convertTabsToSpaces === "boolean") { - options.ConvertTabsToSpaces = config.convertTabsToSpaces; - } - - return options; -} +} \ No newline at end of file diff --git a/lib/main/tsconfig/simpleValidator.ts b/lib/main/tsconfig/simpleValidator.ts deleted file mode 100644 index d9f08c59f..000000000 --- a/lib/main/tsconfig/simpleValidator.ts +++ /dev/null @@ -1,85 +0,0 @@ -/// Not useful for user input validation -// But great for simple config validation -// works only by "n" valid options - -export var types = { - string: 'string', - boolean: 'boolean', - number: 'number', - object: 'object', - array: 'array' -} - -export interface ValidationInfo { - [name: string]: { - validValues?: string[]; - type?: string; - } -} - -export interface Errors { - invalidValues: string[]; - extraKeys: string[]; - errorMessage: string; -} - -export class SimpleValidator { - - private potentialLowerCaseMatch: { [key: string]: string }; - constructor(public validationInfo: ValidationInfo) { - this.potentialLowerCaseMatch = {}; - Object.keys(validationInfo).forEach(k=> this.potentialLowerCaseMatch[k.toLowerCase()] = k); - } - - validate(config: any): Errors { - var keys = Object.keys(config); - var errors = { invalidValues: [], extraKeys: [], errorMessage: '' }; - keys.forEach(k=> { - // Check extra keys - if (!this.validationInfo[k]) { - if (this.potentialLowerCaseMatch[k]) { - errors.extraKeys.push(`Key: '${k}' is a potential lower case match for '${this.potentialLowerCaseMatch[k]}'. Fix the casing.`); - } - else { - errors.extraKeys.push(`Unknown Option: ${k}`) - } - } - // Do validation - else { - var validationInfo = this.validationInfo[k]; - var value: any = config[k]; - if (validationInfo.type && validationInfo.type === 'array') { - if (!Array.isArray(value)) { - errors.invalidValues.push(`Key: '${k}' has an invalid type: ${typeof value}`) - } - } - else { - if (validationInfo.validValues && validationInfo.validValues.length) { - var validValues = validationInfo.validValues; - if (!validValues.some(valid => valid.toLowerCase() === value.toLowerCase())) { - errors.invalidValues.push(`Key: '${k}' has an invalid value: ${value}`); - } - } - if (validationInfo.type && typeof value !== validationInfo.type) { - errors.invalidValues.push(`Key: '${k}' has an invalid type: ${typeof value}`) - } - } - } - }); - - var total = errors.invalidValues.concat(errors.extraKeys); - if (total.length) { - errors.errorMessage = total.join("\n"); - } - - return errors; - } -} - - -export function createMap(arr: string[]): { [key: string]: boolean } { - return arr.reduce((result: { [key: string]: boolean }, key: string) => { - result[key] = true; - return result; - }, <{ [key: string]: boolean }>{}); -} diff --git a/lib/main/tsconfig/tsconfig.ts b/lib/main/tsconfig/tsconfig.ts deleted file mode 100644 index 8b0b7a4a6..000000000 --- a/lib/main/tsconfig/tsconfig.ts +++ /dev/null @@ -1,909 +0,0 @@ -import * as fsu from "../utils/fsUtil"; - -import simpleValidator = require('./simpleValidator'); -var types = simpleValidator.types; - -// Most compiler options come from require('typescript').CompilerOptions, but -// 'module' and 'target' cannot use the same enum as that interface since we -// do not want to force users to put magic numbers in their tsconfig files -// Possible: Use require('typescript').parseConfigFile in TS1.5 -// NOTE: see the changes in `commandLineParser.ts` in the TypeScript sources to see what needs updating -/** - * When adding you need to - * 0 Add in this interface - * 1 Add to the validation - * 2 If its an enum : Update `typescriptEnumMap` - * 3 If its a path : Update the `make relative` code - */ -interface CompilerOptions { - allowJs?: boolean; - allowNonTsExtensions?: boolean; - allowSyntheticDefaultImports?: boolean; - allowUnreachableCode?: boolean; - allowUnusedLabels?: boolean; - alwaysStrict?: boolean; - baseUrl?: string; - charset?: string; - codepage?: number; - declaration?: boolean; - declarationDir?: string; - diagnostics?: boolean; - emitBOM?: boolean; - emitDecoratorMetadata?: boolean; // Experimental. Emits addition type information for this reflection API https://github.com/rbuckton/ReflectDecorators - experimentalAsyncFunctions?: boolean; - experimentalDecorators?: boolean; // Experimental. Needed for the next option `emitDecoratorMetadata` see : https://github.com/Microsoft/TypeScript/pull/3330 - forceConsistentCasingInFileNames?: boolean; - help?: boolean; - importHelpers?: boolean; - inlineSourceMap?: boolean; - inlineSources?: boolean; - isolatedModules?: boolean; - jsx?: string; - jsxFactory?: string; - lib?: string[]; - listFiles?: boolean; - locale?: string; - mapRoot?: string; // Optionally Specifies the location where debugger should locate map files after deployment - module?: string; - moduleResolution?: string; - newLine?: string; - noEmit?: boolean; - noEmitHelpers?: boolean; - noEmitOnError?: boolean; - noErrorTruncation?: boolean; - noFallthroughCasesInSwitch?: boolean; - noImplicitAny?: boolean; // Error on inferred `any` type - noImplicitReturns?: boolean; - noImplicitThis?: boolean; - noImplicitUseStrict?: boolean; - noLib?: boolean; - noLibCheck?: boolean; - noResolve?: boolean; - noUnusedLocals?: boolean; - noUnusedParameters?: boolean; - out?: string; // Deprecated. Use outFile instead - outDir?: string; // Redirect output structure to this directory - outFile?: string; // new name for out - paths?: { [pattern: string]: string[] }; - preserveConstEnums?: boolean; - pretty?: boolean; // Experimental - project?: string; - reactNamespace?: string; - removeComments?: boolean; // Do not emit comments in output - rootDir?: string; - rootDirs?: string[]; - skipDefaultLibCheck?: boolean; - skipLibCheck?: boolean; - sourceMap?: boolean; // Generates SourceMaps (.map files) - sourceRoot?: string; // Optionally specifies the location where debugger should locate TypeScript source files after deployment - strictNullChecks?: boolean; - stripInternal?: boolean; - suppressExcessPropertyErrors?: boolean; // Optionally disable strict object literal assignment checking - suppressImplicitAnyIndexErrors?: boolean; - target?: string; // 'es3'|'es5'|'es6'|'es2015'|'es2016'|'es2017'|'esnext', defaults to es5 - typeRoots?: string[]; - types?: string[]; - version?: boolean; - watch?: boolean; -} - -var compilerOptionsValidation: simpleValidator.ValidationInfo = { - allowJs: { type: types.boolean }, - allowNonTsExtensions: { type: types.boolean }, - allowSyntheticDefaultImports: { type: types.boolean }, - allowUnreachableCode: { type: types.boolean }, - allowUnusedLabels: { type: types.boolean }, - alwaysStrict: { type: types.boolean }, - baseUrl: { type: types.string }, - charset: { type: types.string }, - codepage: { type: types.number }, - declaration: { type: types.boolean }, - declarationDir: { type: types.string }, - diagnostics: { type: types.boolean }, - emitBOM: { type: types.boolean }, - emitDecoratorMetadata: { type: types.boolean }, - experimentalAsyncFunctions: { type: types.boolean }, - experimentalDecorators: { type: types.boolean }, - forceConsistentCasingInFileNames: { type: types.boolean }, - help: { type: types.boolean }, - importHelpers: { type: types.boolean }, - inlineSourceMap: { type: types.boolean }, - inlineSources: { type: types.boolean }, - isolatedModules: { type: types.boolean }, - jsx: { type: types.string, validValues: ['preserve', 'react'] }, - jsxFactory: { type: types.string }, - lib: { type: types.array }, - listFiles: { type: types.boolean }, - locals: { type: types.string }, - mapRoot: { type: types.string }, - module: { type: types.string, validValues: ['commonjs', 'amd', 'system', 'umd', 'es6', 'es2015', 'none'] }, - moduleResolution: { type: types.string, validValues: ['classic', 'node'] }, - newLine: { type: types.string }, - noEmit: { type: types.boolean }, - noEmitHelpers: { type: types.boolean }, - noEmitOnError: { type: types.boolean }, - noErrorTruncation: { type: types.boolean }, - noFallthroughCasesInSwitch: { type: types.boolean }, - noImplicitAny: { type: types.boolean }, - noImplicitReturns: { type: types.boolean }, - noImplicitThis: { type: types.boolean }, - noImplicitUseStrict: { type: types.boolean }, - noLib: { type: types.boolean }, - noLibCheck: { type: types.boolean }, - noResolve: { type: types.boolean }, - noUnusedLocals: { type: types.boolean }, - noUnusedParameters: { type: types.boolean }, - out: { type: types.string }, - outDir: { type: types.string }, - outFile: { type: types.string }, - paths: { type: types.object }, - preserveConstEnums: { type: types.boolean }, - pretty: { type: types.boolean }, - project: { type: types.string }, - reactNamespace: { type: types.string }, - removeComments: { type: types.boolean }, - rootDir: { type: types.string }, - rootDirs: { type: types.object }, - skipDefaultLibCheck: { type: types.boolean }, - skipLibCheck: { type: types.boolean }, - sourceMap: { type: types.boolean }, - sourceRoot: { type: types.string }, - strictNullChecks: { type: types.boolean }, - stripInternal: { type: types.boolean }, - suppressExcessPropertyErrors: { type: types.boolean }, - suppressImplicitAnyIndexErrors: { type: types.boolean }, - target: { type: types.string, validValues: ['es3', 'es5', 'es6', 'es2015', 'es2016', 'es2017', 'esnext'] }, - typeRoots: { type: types.array }, - types: { type: types.array }, - version: { type: types.boolean }, - watch: { type: types.boolean }, -} -var validator = new simpleValidator.SimpleValidator(compilerOptionsValidation); - -interface UsefulFromPackageJson { - /** We need this as this is the name the user is going to import **/ - name: string; - /** we need this to figure out the basePath (will depend on how `outDir` is relative to this directory) */ - directory: string; - /** This is going to be typescript.definition */ - definition: string; - main: string; -} - -/** - * This is the JSON.parse result of a tsconfig.json - */ -interface TypeScriptProjectRawSpecification { - compilerOptions?: CompilerOptions; - exclude?: string[]; // optional: An array of 'glob / minimatch / RegExp' patterns to specify directories / files to exclude - files?: string[]; // optional: paths to files - filesGlob?: string[]; // optional: An array of 'glob / minimatch / RegExp' patterns to specify source files - formatCodeOptions?: formatting.FormatCodeOptions; // optional: formatting options - compileOnSave?: boolean; // optional: compile on save. Ignored to build tools. Used by IDEs - buildOnSave?: boolean; - externalTranspiler?: string | { name: string; options?: any }; - scripts?: { postbuild?: string }; - atom?: { rewriteTsconfig?: boolean, formatOnSave?: boolean }; -} - -/** - * This is `TypeScriptProjectRawSpecification` parsed further - * Designed for use throughout out code base - */ -export interface TypeScriptProjectSpecification { - compilerOptions: ts.CompilerOptions; - files: string[]; - typings: string[]; // These are considered externs for .d.ts. Note : duplicated in files - filesGlob?: string[]; - formatCodeOptions: ts.FormatCodeOptions; - compileOnSave: boolean; - buildOnSave: boolean; - package?: UsefulFromPackageJson; - externalTranspiler?: string | { name: string; options?: any }; - scripts: { postbuild?: string }; - atom: { rewriteTsconfig: boolean, formatOnSave: boolean }; -} - -///////// FOR USE WITH THE API ///////////// - -export interface TypeScriptProjectFileDetails { - /** The path to the project file. This acts as the baseDIR */ - projectFileDirectory: string; - /** The actual path of the project file (including tsconfig.json) */ - projectFilePath: string; - project: TypeScriptProjectSpecification; - inMemory: boolean; -} - - -////////////////////////////////////////////////////////////////////// - -export var errors = { - GET_PROJECT_INVALID_PATH: 'The path used to query for tsconfig.json does not exist', - GET_PROJECT_NO_PROJECT_FOUND: 'No Project Found', - GET_PROJECT_FAILED_TO_OPEN_PROJECT_FILE: 'Failed to fs.readFileSync the project file', - GET_PROJECT_JSON_PARSE_FAILED: 'Failed to JSON.parse the project file', - GET_PROJECT_GLOB_EXPAND_FAILED: 'Failed to expand filesGlob in the project file', - GET_PROJECT_PROJECT_FILE_INVALID_OPTIONS: 'Project file contains invalid options', - - CREATE_FILE_MUST_EXIST: 'The Typescript file must exist on disk in order to create a project', - CREATE_PROJECT_ALREADY_EXISTS: 'Project file already exists', -}; -export interface GET_PROJECT_JSON_PARSE_FAILED_Details { - projectFilePath: string; - error: Error; -} -export interface GET_PROJECT_PROJECT_FILE_INVALID_OPTIONS_Details { - projectFilePath: string; - errorMessage: string; -} -export interface GET_PROJECT_GLOB_EXPAND_FAILED_Details { - glob: string[]; - projectFilePath: string; - errorMessage: string; -} -export interface GET_PROJECT_NO_PROJECT_FOUND_Details { - projectFilePath: string; - errorMessage: string; -} -function errorWithDetails(error: Error, details: T): Error { - error.details = details; - return error; -} - -import fs = require('fs'); -import path = require('path'); -import tsconfig = require('tsconfig'); -import os = require('os'); -import detectIndent = require('detect-indent'); -import detectNewline = require('detect-newline'); -import extend = require('xtend'); -import formatting = require('./formatting'); - -var projectFileName = 'tsconfig.json'; - -/** - * This is what we write to new files - */ -var defaultFilesGlob = [ - "**/*.ts", - "**/*.tsx", - "!node_modules/**", -]; -/** - * This is what we use when the user doesn't specify a files / filesGlob - */ -var invisibleFilesGlob = '{**/*.ts,**/*.tsx}'; - -export var defaults: ts.CompilerOptions = { - target: ts.ScriptTarget.ES5, - module: ts.ModuleKind.CommonJS, - moduleResolution: ts.ModuleResolutionKind.NodeJs, - isolatedModules: false, - jsx: ts.JsxEmit.React, - experimentalDecorators: true, - emitDecoratorMetadata: true, - declaration: false, - noImplicitAny: false, - noImplicitUseStrict: false, - removeComments: true, - noLib: false, - preserveConstEnums: true, - suppressImplicitAnyIndexErrors: true -}; - -var typescriptEnumMap = { - target: { - 'es3': ts.ScriptTarget.ES3, - 'es5': ts.ScriptTarget.ES5, - 'es6': ts.ScriptTarget.ES2015, - 'es2015': ts.ScriptTarget.ES2015, - 'es2016': ts.ScriptTarget.ES2016, - 'es2017': ts.ScriptTarget.ES2017, - 'esnext': ts.ScriptTarget.Latest, - }, - module: { - 'none': ts.ModuleKind.None, - 'commonjs': ts.ModuleKind.CommonJS, - 'amd': ts.ModuleKind.AMD, - 'umd': ts.ModuleKind.UMD, - 'system': ts.ModuleKind.System, - 'es6': ts.ModuleKind.ES2015, - 'es2015': ts.ModuleKind.ES2015, - }, - moduleResolution: { - 'node': ts.ModuleResolutionKind.NodeJs, - 'classic': ts.ModuleResolutionKind.Classic - }, - jsx: { - 'preserve': ts.JsxEmit.Preserve, - 'react': ts.JsxEmit.React - }, - newLine: { - 'CRLF': ts.NewLineKind.CarriageReturnLineFeed, - 'LF': ts.NewLineKind.LineFeed - } -}; - -var jsonEnumMap: any = {}; -Object.keys(typescriptEnumMap).forEach(name => { - jsonEnumMap[name] = reverseKeysAndValues(typescriptEnumMap[name]); -}); - -function mixin(target: any, source: any): any { - for (var key in source) { - target[key] = source[key]; - } - return target; -} - -function rawToTsCompilerOptions(jsonOptions: CompilerOptions, projectDir: string): ts.CompilerOptions { - // Cannot use Object.create because the compiler checks hasOwnProperty - var compilerOptions = mixin({}, defaults); - for (var key in jsonOptions) { - if (typescriptEnumMap[key]) { - let name = jsonOptions[key]; - let map = typescriptEnumMap[key]; - compilerOptions[key] = map[name.toLowerCase()] || map[name.toUpperCase()]; - } - else { - compilerOptions[key] = jsonOptions[key]; - } - } - - if (compilerOptions.outDir !== undefined) { - compilerOptions.outDir = path.resolve(projectDir, compilerOptions.outDir); - } - - if (compilerOptions.rootDir !== undefined) { - compilerOptions.rootDir = path.resolve(projectDir, compilerOptions.rootDir); - } - - if (compilerOptions.out !== undefined) { - // Till out is removed. Support by just copying it to `outFile` - compilerOptions.outFile = path.resolve(projectDir, compilerOptions.out); - } - - if (compilerOptions.outFile !== undefined) { - compilerOptions.outFile = path.resolve(projectDir, compilerOptions.outFile); - } - - if (compilerOptions.baseUrl !== undefined) { - compilerOptions.baseUrl = path.resolve(projectDir, compilerOptions.baseUrl); - } - - if (compilerOptions.rootDirs !== undefined && Array.isArray(compilerOptions.rootDirs)) { - compilerOptions.rootDirs = compilerOptions.rootDirs.map(function(dir) { - return path.resolve(projectDir, dir) - }); - } - - return compilerOptions; -} - -function tsToRawCompilerOptions(compilerOptions: ts.CompilerOptions): CompilerOptions { - // Cannot use Object.create because JSON.stringify will only serialize own properties - var jsonOptions = mixin({}, compilerOptions); - - Object.keys(compilerOptions).forEach((key) => { - if (jsonEnumMap[key] && compilerOptions[key]) { - var value = compilerOptions[key]; - jsonOptions[key] = jsonEnumMap[key][value]; - } - }); - - return jsonOptions; -} - -export function getDefaultInMemoryProject(srcFile: string): TypeScriptProjectFileDetails { - var dir = fs.lstatSync(srcFile).isDirectory() ? srcFile : path.dirname(srcFile); - - var files = [srcFile]; - var typings = getDefinitionsForNodeModules(dir, files); - files = increaseProjectForReferenceAndImports(files); - files = uniq(files.map(fsu.consistentPath)); - - let project: TypeScriptProjectSpecification = { - compilerOptions: defaults, - files, - typings: typings.ours.concat(typings.implicit), - formatCodeOptions: formatting.defaultFormatCodeOptions(), - compileOnSave: true, - buildOnSave: false, - scripts: {}, - atom: { rewriteTsconfig: false, formatOnSave: false }, - }; - - return { - projectFileDirectory: dir, - projectFilePath: dir + '/' + projectFileName, - project: project, - inMemory: true - }; -} - -/** Given an src (source file or directory) goes up the directory tree to find the project specifications. - * Use this to bootstrap the UI for what project the user might want to work on. - * Note: Definition files (.d.ts) are considered thier own project - */ -export function getProjectSync(pathOrSrcFile: string): TypeScriptProjectFileDetails { - - if (!fs.existsSync(pathOrSrcFile)) { - throw new Error(errors.GET_PROJECT_INVALID_PATH); - } - - var dir = fs.lstatSync(pathOrSrcFile).isDirectory() ? pathOrSrcFile : path.dirname(pathOrSrcFile); - var projectFile = tsconfig.resolveSync(dir); - - if (!projectFile) { - throw errorWithDetails( - new Error(errors.GET_PROJECT_NO_PROJECT_FOUND), { projectFilePath: fsu.consistentPath(pathOrSrcFile), errorMessage: 'not found' }); - } - - var projectFileDirectory = path.dirname(projectFile) + path.sep; - - // We now have a valid projectFile. Parse it: - var projectSpec: TypeScriptProjectRawSpecification; - var projectFileTextContent: string; - - try { - projectFileTextContent = fs.readFileSync(projectFile, 'utf8'); - } catch (ex) { - throw new Error(errors.GET_PROJECT_FAILED_TO_OPEN_PROJECT_FILE); - } - - try { - projectSpec = tsconfig.parseFileSync(projectFileTextContent, projectFile, { resolvePaths: false }); - } catch (ex) { - throw errorWithDetails( - new Error(errors.GET_PROJECT_JSON_PARSE_FAILED), { projectFilePath: fsu.consistentPath(projectFile), error: ex.message }); - } - - /** Setup defaults for atom key */ - if (!projectSpec.atom) { - projectSpec.atom = { - rewriteTsconfig: false, - } - } - - if (projectSpec.filesGlob) { // for filesGlob we keep the files in sync - var prettyJSONProjectSpec = prettyJSON(projectSpec, detectIndent(projectFileTextContent).indent, detectNewline(projectFileTextContent)); - - if (prettyJSONProjectSpec !== projectFileTextContent && projectSpec.atom.rewriteTsconfig) { - fs.writeFileSync(projectFile, prettyJSONProjectSpec); - } - } - - var pkg: UsefulFromPackageJson = null; - try { - var packagePath = travelUpTheDirectoryTreeTillYouFind(projectFileDirectory, 'package.json'); - if (packagePath) { - let packageJSONPath = getPotentiallyRelativeFile(projectFileDirectory, packagePath); - let parsedPackage = JSON.parse(fs.readFileSync(packageJSONPath).toString()); - pkg = { - main: parsedPackage.main, - name: parsedPackage.name, - directory: path.dirname(packageJSONPath), - definition: parsedPackage.typescript && parsedPackage.typescript.definition - }; - } - } - catch (ex) { - // console.error('no package.json found', projectFileDirectory, ex.message); - } - - var project: TypeScriptProjectSpecification = { - compilerOptions: {}, - files: projectSpec.files.map(x => path.resolve(projectFileDirectory, x)), - filesGlob: projectSpec.filesGlob, - formatCodeOptions: formatting.makeFormatCodeOptions(projectSpec.formatCodeOptions), - compileOnSave: projectSpec.compileOnSave == undefined ? true : projectSpec.compileOnSave, - package: pkg, - typings: [], - externalTranspiler: projectSpec.externalTranspiler == undefined ? undefined : projectSpec.externalTranspiler, - scripts: projectSpec.scripts || {}, - buildOnSave: !!projectSpec.buildOnSave, - atom: { rewriteTsconfig: false, formatOnSave: !!projectSpec.atom.formatOnSave } - }; - - // Validate the raw compiler options before converting them to TS compiler options - var validationResult = validator.validate(projectSpec.compilerOptions); - if (validationResult.errorMessage) { - throw errorWithDetails( - new Error(errors.GET_PROJECT_PROJECT_FILE_INVALID_OPTIONS), - { projectFilePath: fsu.consistentPath(projectFile), errorMessage: validationResult.errorMessage } - ); - } - - // Convert the raw options to TS options - project.compilerOptions = rawToTsCompilerOptions(projectSpec.compilerOptions, projectFileDirectory); - - // Expand files to include references - project.files = increaseProjectForReferenceAndImports(project.files); - - // Expand files to include node_modules / package.json / typescript.definition - var typings = getDefinitionsForNodeModules(dir, project.files); - project.files = project.files.concat(typings.implicit); - project.typings = typings.ours.concat(typings.implicit); - project.files = project.files.concat(typings.packagejson); - - // Normalize to "/" for all files - // And take the uniq values - project.files = uniq(project.files.map(fsu.consistentPath)); - projectFileDirectory = removeTrailingSlash(fsu.consistentPath(projectFileDirectory)); - - return { - projectFileDirectory: projectFileDirectory, - projectFilePath: projectFileDirectory + '/' + projectFileName, - project: project, - inMemory: false - }; - -} - -/** Creates a project by source file location. Defaults are assumed unless overriden by the optional spec. */ -export function createProjectRootSync(srcFile: string, defaultOptions?: ts.CompilerOptions) { - if (!fs.existsSync(srcFile)) { - throw new Error(errors.CREATE_FILE_MUST_EXIST); - } - - // Get directory - var dir = fs.lstatSync(srcFile).isDirectory() ? srcFile : path.dirname(srcFile); - var projectFilePath = path.normalize(dir + '/' + projectFileName); - - if (fs.existsSync(projectFilePath)) - throw new Error(errors.CREATE_PROJECT_ALREADY_EXISTS); - - // We need to write the raw spec - var projectSpec: TypeScriptProjectRawSpecification = {}; - projectSpec.compilerOptions = tsToRawCompilerOptions(defaultOptions || defaults); - projectSpec.exclude = ["node_modules", "typings/browser", "typings/browser.d.ts"]; - projectSpec.compileOnSave = true; - projectSpec.buildOnSave = false; - projectSpec.atom = { - rewriteTsconfig: false - }; - - fs.writeFileSync(projectFilePath, prettyJSON(projectSpec)); - return getProjectSync(srcFile); -} - -///////////////////////////////////////////// -/////////////// UTILITIES /////////////////// -///////////////////////////////////////////// - -function increaseProjectForReferenceAndImports(files: string[]): string[] { - - var filesMap = simpleValidator.createMap(files); - var willNeedMoreAnalysis = (file: string) => { - if (!filesMap[file]) { - filesMap[file] = true; - files.push(file); - return true; - } else { - return false; - } - } - - var getReferencedOrImportedFiles = (files: string[]): string[] => { - var referenced: string[][] = []; - - files.forEach(file => { - try { - var content = fs.readFileSync(file).toString(); - } - catch (ex) { - // if we cannot read a file for whatever reason just quit - return; - } - var preProcessedFileInfo = ts.preProcessFile(content, true), - dir = path.dirname(file); - - let extensions = ['.ts', '.d.ts', '.tsx']; - function getIfExists(filePathNoExt: string) { - for (let ext of extensions) { - if (fs.existsSync(filePathNoExt + ext)) { - return filePathNoExt + ext; - } - } - } - - referenced.push( - preProcessedFileInfo.referencedFiles.map(fileReference => { - // We assume reference paths are always relative - var file = path.resolve(dir, fsu.consistentPath(fileReference.fileName)); - // Try by itself then with extensions - if (fs.existsSync(file)) { - return file; - } - return getIfExists(file); - }).filter(file => !!file) - .concat( - preProcessedFileInfo.importedFiles - .filter((fileReference) => pathIsRelative(fileReference.fileName)) - .map(fileReference => { - let fileNoExt = path.resolve(dir, fileReference.fileName); - let file = getIfExists(fileNoExt); - if (!file) { - file = getIfExists(`${file}/index`); - } - return file; - }).filter(file => !!file) - ) - ); - }); - - return selectMany(referenced); - } - - var more = getReferencedOrImportedFiles(files) - .filter(willNeedMoreAnalysis); - while (more.length) { - more = getReferencedOrImportedFiles(files) - .filter(willNeedMoreAnalysis); - } - - return files; -} - -/** There can be only one typing by name */ -interface Typings { - [name: string]: { - filePath: string; - /** Right now its just INF as we don't do version checks. First one wins! */ - version: number; // (Simple : maj * 1000000 + min). Don't care about patch - }; -} - -/** - * Spec - * We will expand on files making sure that we don't have a `typing` with the same name - * Also if two node_modules reference a similar sub project (and also recursively) then the one with latest `version` field wins - */ -function getDefinitionsForNodeModules(projectDir: string, files: string[]): { ours: string[]; implicit: string[], packagejson: string[] } { - let packagejson = []; - - /** TODO use later when we care about versions */ - function versionStringToNumber(version: string): number { - var [maj, min, patch] = version.split('.'); - return parseInt(maj) * 1000000 + parseInt(min); - } - - var typings: Typings = {}; - - // Find our `typings` (anything in a typings folder with extension `.d.ts` is considered a typing) - // These are INF powerful - var ourTypings = files - .filter(f => path.basename(path.dirname(f)) == 'typings' && endsWith(f, '.d.ts') - || path.basename(path.dirname(path.dirname(f))) == 'typings' && endsWith(f, '.d.ts')); - ourTypings.forEach(f => typings[path.basename(f)] = { filePath: f, version: Infinity }); - var existing = createMap(files.map(fsu.consistentPath)); - - function addAllReferencedFilesWithMaxVersion(file: string) { - var dir = path.dirname(file); - try { - var content = fs.readFileSync(file).toString(); - } - catch (ex) { - // if we cannot read a file for whatever reason just quit - return; - } - var preProcessedFileInfo = ts.preProcessFile(content, true); - var files = preProcessedFileInfo.referencedFiles.map(fileReference => { - // We assume reference paths are always relative - var file = path.resolve(dir, fileReference.fileName); - // Try by itself, .d.ts - if (fs.existsSync(file)) { - return file; - } - if (fs.existsSync(file + '.d.ts')) { - return file + '.d.ts'; - } - }).filter(f => !!f); - - // Only ones we don't have by name yet - // TODO: replace INF with an actual version - files = files - .filter(f => !typings[path.basename(f)] || typings[path.basename(f)].version > Infinity); - // Add these - files.forEach(f => typings[path.basename(f)] = { filePath: f, version: Infinity }); - // Keep expanding - files.forEach(f => addAllReferencedFilesWithMaxVersion(f)); - } - - // Keep going up till we find node_modules - // at that point read the `package.json` for each file in node_modules - // And then if that package.json has `typescript.definition` we import that file - try { - var node_modules = travelUpTheDirectoryTreeTillYouFind(projectDir, 'node_modules', true); - - // For each sub directory of node_modules look at package.json and then `typescript.definition` - var moduleDirs = getDirs(node_modules); - for (let moduleDir of moduleDirs) { - try { - var package_json = JSON.parse(fs.readFileSync(`${moduleDir}/package.json`).toString()); - packagejson.push(`${moduleDir}/package.json`); - } - catch (ex) { - // Can't read package.json ... no worries ... move on to other modules - continue; - } - if (package_json.typescript && package_json.typescript.definition) { - - let file = path.resolve(moduleDir, './', package_json.typescript.definition); - - typings[path.basename(file)] = { - filePath: file, - version: Infinity - }; - // Also add any files that this `.d.ts` references as long as they don't conflict with what we have - addAllReferencedFilesWithMaxVersion(file); - } - } - - } - catch (ex) { - if (ex.message == "not found") { - // Sure we didn't find node_modules - // Thats cool - } - // this is best effort only at the moment - else { - console.error('Failed to read package.json from node_modules due to error:', ex, ex.stack); - } - } - - var all = Object.keys(typings) - .map(typing => typings[typing].filePath) - .map(x => fsu.consistentPath(x)); - var implicit = all - .filter(x => !existing[x]); - var ours = all - .filter(x => existing[x]); - - return { implicit, ours, packagejson }; -} - -export function prettyJSON(object: any, indent: string | number = 4, newLine: string = os.EOL): string { - var cache = []; - var value = JSON.stringify( - object, - // fixup circular reference - function(key, value) { - if (typeof value === 'object' && value !== null) { - if (cache.indexOf(value) !== -1) { - // Circular reference found, discard key - return; - } - // Store value in our collection - cache.push(value); - } - return value; - }, - indent - ); - value = value.replace(/(?:\r\n|\r|\n)/g, newLine) + newLine; - cache = null; - return value; -} - -// Not particularly awesome e.g. '/..foo' will be not relative -export function pathIsRelative(str: string) { - if (!str.length) return false; - return str[0] == '.' || str.substring(0, 2) == "./" || str.substring(0, 3) == "../"; -} - -// Not optimized -function selectMany(arr: T[][]): T[] { - var result = []; - for (var i = 0; i < arr.length; i++) { - for (var j = 0; j < arr[i].length; j++) { - result.push(arr[i][j]); - } - } - return result; -} - -export function endsWith(str: string, suffix: string): boolean { - return str && str.indexOf(suffix, str.length - suffix.length) !== -1; -} - -function uniq(arr: string[]): string[] { - var map = simpleValidator.createMap(arr); - return Object.keys(map); -} - -/** - * Converts "C:\boo" , "C:\boo\foo.ts" => "./foo.ts"; Works on unix as well. - */ -export function makeRelativePath(relativeFolder: string, filePath: string) { - var relativePath = path.relative(relativeFolder, filePath).split('\\').join('/'); - if (relativePath[0] !== '.') { - relativePath = './' + relativePath; - } - return relativePath; -} - -export function removeExt(filePath: string) { - return filePath.substr(0, filePath.lastIndexOf('.')); -} - -export function removeTrailingSlash(filePath: string) { - if (!filePath) return filePath; - if (endsWith(filePath, '/')) return filePath.substr(0, filePath.length - 1); - return filePath; -} - -/** - * returns the path if found - * @throws an error "not found" if not found */ -export function travelUpTheDirectoryTreeTillYouFind(dir: string, fileOrDirectory: string, - /** This is useful if we don't want to file `node_modules from inside node_modules` */ - abortIfInside = false): string { - while (fs.existsSync(dir)) { // while directory exists - - var potentialFile = dir + '/' + fileOrDirectory; - - /** This means that we were *just* in this directory */ - if (before == potentialFile) { - if (abortIfInside) { - throw new Error("not found") - } - } - - if (fs.existsSync(potentialFile)) { // found it - return potentialFile; - } - else { // go up - var before = dir; - dir = path.dirname(dir); - // At root: - if (dir == before) throw new Error("not found"); - } - } -} - -export function getPotentiallyRelativeFile(basePath: string, filePath: string) { - if (pathIsRelative(filePath)) { - return fsu.consistentPath(path.resolve(basePath, filePath)); - } - return fsu.consistentPath(filePath); -} - -function getDirs(rootDir: string): string[] { - var files = fs.readdirSync(rootDir) - var dirs = [] - - for (var file of files) { - if (file[0] != '.') { - var filePath = `${rootDir}/${file}` - var stat = fs.statSync(filePath); - - if (stat.isDirectory()) { - dirs.push(filePath) - } - } - } - return dirs -} - -/** - * Create a quick lookup map from list - */ -export function createMap(arr: string[]): { [string: string]: boolean } { - return arr.reduce((result: { [string: string]: boolean }, key: string) => { - result[key] = true; - return result; - }, <{ [string: string]: boolean }>{}); -} - -/** - * Turns keys into values and values into keys - */ -function reverseKeysAndValues(obj) { - var toret = {}; - Object.keys(obj).forEach(function(key) { - toret[obj[key]] = key; - }); - return toret; -} diff --git a/lib/main/typescriptBuffer.ts b/lib/main/typescriptBuffer.ts new file mode 100644 index 000000000..cdd8f0e2f --- /dev/null +++ b/lib/main/typescriptBuffer.ts @@ -0,0 +1,134 @@ +// A class to keep all changes to the buffer in sync with tsserver. This is mainly used with +// the editor panes, but is also useful for editor-less buffer changes (renameRefactor). +import {CompositeDisposable} from "atom" +import {TypescriptServiceClient as Client} from "../client/client" +import {EventEmitter} from "events" +import {isTypescriptFile} from "./atom/utils" + +export class TypescriptBuffer { + // Timestamps for buffer events + changedAt: number = 0 + changedAtBatch: number = 0 + + // Promise that resolves to the correct client for this filePath + private clientPromise?: Promise + + // Flag that signifies if tsserver has an open view of this file + isOpen: boolean + + private events = new EventEmitter() + private subscriptions = new CompositeDisposable() + + constructor( + public buffer: TextBuffer.ITextBuffer, + public getClient: (filePath: string) => Promise + ) { + this.subscriptions.add(buffer.onDidChange(this.onDidChange)) + this.subscriptions.add(buffer.onDidChangePath(this.onDidSave)) + this.subscriptions.add(buffer.onDidDestroy(this.dispose)) + this.subscriptions.add(buffer.onDidSave(this.onDidSave)) + this.subscriptions.add(buffer.onDidStopChanging(this.onDidStopChanging)) + + this.open() + } + + async open() { + const filePath = this.buffer.getPath() + + if (isTypescriptFile(filePath)) { + // Set isOpen before we actually open the file to enqueue any changed events + this.isOpen = true + + this.clientPromise = this.getClient(filePath) + const client = await this.clientPromise + + await client.executeOpen({ + file: filePath, + fileContent: this.buffer.getText() + }) + + this.events.emit("opened") + } + } + + // If there are any pending changes, flush them out to the Typescript server + async flush() { + if (this.changedAt > this.changedAtBatch) { + const prevDelay = this.buffer.stoppedChangingDelay + try { + this.buffer.stoppedChangingDelay = 0 + this.buffer.scheduleDidStopChangingEvent() + await new Promise(resolve => { + const {dispose} = this.buffer.onDidStopChanging(() => { + dispose() + resolve() + }) + }) + } finally { + this.buffer.stoppedChangingDelay = prevDelay + } + } + } + + dispose = () => { + this.subscriptions.dispose() + + if (this.isOpen && this.clientPromise) { + this.clientPromise.then(client => + client.executeClose({file: this.buffer.getPath()})) + } + } + + on(name: "saved", callback: () => any): this // saved after waiting for any pending changes + on(name: "opened", callback: () => any): this // the file is opened + on(name: "changed", callback: () => any): this // tsserver view of the file has changed + on(name: string, callback: () => any): this { + this.events.on(name, callback) + return this + } + + onDidChange = () => { + this.changedAt = Date.now() + } + + onDidSave = async () => { + // Check if there isn't a onDidStopChanging event pending. + const {changedAt, changedAtBatch} = this + if (changedAt && changedAt > changedAtBatch) { + await new Promise(resolve => this.events.once("changed", resolve)) + } + + this.events.emit("saved") + } + + onDidStopChanging = async ({changes}: {changes: any[]}) => { + // Don't update changedAt or emit any events if there are no actual changes or file isn't open + if (changes.length === 0 || !this.isOpen || !this.clientPromise) { + return + } + + this.changedAtBatch = Date.now() + + const client = await this.clientPromise + const filePath = this.buffer.getPath() + + for (const change of changes) { + const {start, oldExtent, newText} = change + + const end = { + endLine: start.row + oldExtent.row + 1, + endOffset: (oldExtent.row === 0 ? start.column + oldExtent.column: oldExtent.column) + 1 + } + + await client.executeChange({ + ...end, + file: filePath, + line: start.row + 1, + offset: start.column + 1, + insertString: newText, + }) + } + + this.events.emit("changed") + } +} diff --git a/lib/main/typescriptEditorPane.ts b/lib/main/typescriptEditorPane.ts new file mode 100644 index 000000000..0853ad9d2 --- /dev/null +++ b/lib/main/typescriptEditorPane.ts @@ -0,0 +1,242 @@ +import {$} from "atom-space-pen-views" +import {CompositeDisposable} from "atom" +import {debounce, flatten} from "lodash" +import {spanToRange} from "./atom/utils" +import {StatusPanel} from "./atom/components/statusPanel" +import {TypescriptBuffer} from "./typescriptBuffer" +import {TypescriptServiceClient} from "../client/client" +import * as tooltipManager from './atom/tooltipManager' + +interface PaneOptions { + getClient: (filePath: string) => Promise + onDispose: (pane: TypescriptEditorPane) => any + onSave: (pane: TypescriptEditorPane) => any + statusPanel: StatusPanel +} + +export class TypescriptEditorPane implements AtomCore.Disposable { + // Timestamp for activated event + activeAt: number + + buffer: TypescriptBuffer + client?: TypescriptServiceClient + + // Path to the project's tsconfig.json + configFile: string = "" + + filePath: string + isActive = false + isTypescript = false + + private opts: PaneOptions + private isOpen = false + + readonly occurrenceMarkers: AtomCore.IDisplayBufferMarker[] = [] + readonly editor: AtomCore.IEditor + readonly subscriptions = new CompositeDisposable() + + constructor(editor: AtomCore.IEditor, opts: PaneOptions) { + this.editor = editor + this.filePath = editor.getPath() + this.opts = opts + this.buffer = new TypescriptBuffer(editor.buffer, opts.getClient) + .on("changed", this.onChanged) + .on("opened", this.onOpened) + .on("saved", this.onSaved) + + this.isTypescript = isTypescriptGrammar(editor.getGrammar()) + + // Add 'typescript-editor' class to the where typescript is active. + if (this.isTypescript) { + this.editor.element.classList.add('typescript-editor') + } + + this.subscriptions.add(editor.onDidChangeGrammar(grammar => { + this.isTypescript = isTypescriptGrammar(grammar) + })) + + this.setupTooltipView() + } + + dispose() { + this.editor.element.classList.remove('typescript-editor') + this.subscriptions.dispose() + this.opts.onDispose(this) + } + + onActivated = () => { + this.activeAt = Date.now() + this.isActive = true + + if (this.isTypescript && this.filePath) { + this.opts.statusPanel.show() + + // The first activation might happen before we even have a client + if (this.client) { + this.client.executeGetErr({ + files: [this.filePath], + delay: 100 + }) + + this.opts.statusPanel.setVersion(this.client.version) + } + } + + this.opts.statusPanel.setTsConfigPath(this.configFile) + } + + onChanged = () => { + if (!this.client) + return + + this.opts.statusPanel.setBuildStatus(undefined) + + this.client.executeGetErr({ + files: [this.filePath], + delay: 100 + }) + } + + onDeactivated = () => { + this.isActive = false + this.opts.statusPanel.hide() + } + + clearOccurrenceMarkers() { + for (const marker of this.occurrenceMarkers) { + marker.destroy() + } + } + + updateMarkers = debounce(() => { + if (!this.client) + return + + const pos = this.editor.getLastCursor().getBufferPosition() + + this.client.executeOccurances({ + file: this.filePath, + line: pos.row+1, + offset: pos.column+1 + }).then(result => { + this.clearOccurrenceMarkers() + + for (const ref of result.body!) { + const marker = this.editor.markBufferRange(spanToRange(ref)) + this.editor.decorateMarker(marker as any, { + type: "highlight", + class: "atom-typescript-occurrence" + }) + this.occurrenceMarkers.push(marker) + } + }).catch(() => this.clearOccurrenceMarkers()) + }, 100) + + onDidChangeCursorPosition = ({textChanged}: {textChanged: boolean}) => { + if (!this.isTypescript) { + return + } + + if (textChanged) { + this.clearOccurrenceMarkers() + return + } + + this.updateMarkers() + } + + onDidDestroy = () => { + this.dispose() + } + + onOpened = async () => { + this.client = await this.opts.getClient(this.filePath) + + this.subscriptions.add(this.editor.onDidChangeCursorPosition(this.onDidChangeCursorPosition)) + this.subscriptions.add(this.editor.onDidDestroy(this.onDidDestroy)) + + // onOpened might trigger before onActivated so we can't rely on isActive flag + if (atom.workspace.getActiveTextEditor() === this.editor) { + this.isActive = true + this.opts.statusPanel.setVersion(this.client.version) + } + + if (this.isTypescript && this.filePath) { + this.client.executeGetErr({ + files: [this.filePath], + delay: 100 + }) + + this.isOpen = true + + this.client.executeProjectInfo({ + needFileNameList: false, + file: this.filePath + }).then(result => { + this.configFile = result.body!.configFileName + + if (this.isActive) { + this.opts.statusPanel.setTsConfigPath(this.configFile) + } + }, error => null) + } + } + + onSaved = () => { + this.filePath = this.editor.getPath() + + if (this.opts.onSave) { + this.opts.onSave(this) + } + + this.compileOnSave() + } + + async compileOnSave() { + const {client} = this + if (!client) + return + + const result = await client.executeCompileOnSaveAffectedFileList({ + file: this.filePath + }) + + this.opts.statusPanel.setBuildStatus(undefined) + + const fileNames = flatten(result.body.map(project => project.fileNames)) + + if (fileNames.length === 0) { + return + } + + try { + const promises = fileNames.map(file => client.executeCompileOnSaveEmitFile({file})) + const saved = await Promise.all(promises) + + if (!saved.every(res => res.body)) { + throw new Error("Some files failed to emit") + } + + this.opts.statusPanel.setBuildStatus({ + success: true + }) + + } catch (error) { + console.error("Save failed with error", error) + this.opts.statusPanel.setBuildStatus({ + success: false + }) + } + } + + setupTooltipView() { + // subscribe for tooltips + // inspiration : https://github.com/chaika2013/ide-haskell + const editorView = $(atom.views.getView(this.editor)) + tooltipManager.attach(editorView, this.editor) + } +} + +function isTypescriptGrammar(grammar: AtomCore.IGrammar): boolean { + return grammar.scopeName === "source.ts" || grammar.scopeName === "source.tsx" +} diff --git a/lib/tsconfig.json b/lib/tsconfig.json index 045cf265b..3740d8579 100644 --- a/lib/tsconfig.json +++ b/lib/tsconfig.json @@ -1,144 +1,40 @@ { - "compilerOptions": { - "target": "es5", - "module": "commonjs", - "declaration": false, - "noImplicitAny": false, - "removeComments": true, - "noLib": false, - "preserveConstEnums": true, - "outDir": "../dist", - "sourceMap": false, - "jsx": "react", - "types": [ - "byots" - ] - }, - "dts": { - "name": "atom-typescript" - }, - "filesGlob": [ - "./**/*.ts", - "./**/*.tsx", - "../typings/main.d.ts", - "!node_modules/**/*.ts", - "!node_modules/**/*.tsx" - ], - "files": [ - "./globals.ts", - "./hyperclickProvider.ts", - "./linter.ts", - "./main/atom/atomConfig.ts", - "./main/atom/atomUtils.ts", - "./main/atom/autoCompleteProvider.ts", - "./main/atom/buildView.ts", - "./main/atom/commands/commands.ts", - "./main/atom/commands/json2dtsCommands.ts", - "./main/atom/commands/moveFilesHandling.ts", - "./main/atom/commands/outputFileCommands.ts", - "./main/atom/commands/reactCommands.ts", - "./main/atom/components/componentRegistry.ts", - "./main/atom/components/ts-view.ts", - "./main/atom/debugAtomTs.ts", - "./main/atom/editorSetup.ts", - "./main/atom/fileStatusCache.ts", - "./main/atom/gotoHistory.ts", - "./main/atom/onSaveHandler.ts", - "./main/atom/signatureProvider.ts", - "./main/atom/tooltipManager.ts", - "./main/atom/typescriptGrammar.ts", - "./main/atom/views/astView.ts", - "./main/atom/views/awesomePanelView.ts", - "./main/atom/views/contextView.ts", - "./main/atom/views/dependencyView.ts", - "./main/atom/views/documentationView.ts", - "./main/atom/views/fileSymbolsView.ts", - "./main/atom/views/lineMessageView.ts", - "./main/atom/views/mainPanelView.ts", - "./main/atom/views/plainMessageView.ts", - "./main/atom/views/projectSymbolsView.ts", - "./main/atom/views/renameView.ts", - "./main/atom/views/semanticViewGlobals.d.ts", - "./main/atom/views/simpleOverlaySelectionView.ts", - "./main/atom/views/simpleSelectionView.ts", - "./main/atom/views/tooltipView.ts", - "./main/atom/views/typeOverlayView.ts", - "./main/atom/views/view.ts", - "./main/atomts.ts", - "./main/bin/atbuild.ts", - "./main/json2dts/json2dts.ts", - "./main/lang/core/languageServiceHost2.ts", - "./main/lang/core/project.ts", - "./main/lang/fixmyts/astUtils.ts", - "./main/lang/fixmyts/quickFix.ts", - "./main/lang/fixmyts/quickFixes/addClassMember.ts", - "./main/lang/fixmyts/quickFixes/addClassMethod.ts", - "./main/lang/fixmyts/quickFixes/addImportDefaultStatement.ts", - "./main/lang/fixmyts/quickFixes/addImportFromStatement.ts", - "./main/lang/fixmyts/quickFixes/addImportStatement.ts", - "./main/lang/fixmyts/quickFixes/equalsToEquals.ts", - "./main/lang/fixmyts/quickFixes/extractVariable.ts", - "./main/lang/fixmyts/quickFixes/implementInterface.ts", - "./main/lang/fixmyts/quickFixes/quotesToQuotes.ts", - "./main/lang/fixmyts/quickFixes/quoteToTemplate.ts", - "./main/lang/fixmyts/quickFixes/singleLineCommentToJsdoc.ts", - "./main/lang/fixmyts/quickFixes/stringConcatToTemplate.ts", - "./main/lang/fixmyts/quickFixes/typeAssertPropertyAccessToAny.ts", - "./main/lang/fixmyts/quickFixes/typeAssertPropertyAccessToType.ts", - "./main/lang/fixmyts/quickFixes/wrapInProperty.ts", - "./main/lang/fixmyts/quickFixRegistry.ts", - "./main/lang/modules/astToText.ts", - "./main/lang/modules/building.ts", - "./main/lang/modules/formatting.ts", - "./main/lang/modules/getPathCompletions.ts", - "./main/lang/modules/moveFiles.ts", - "./main/lang/modules/programDependencies.ts", - "./main/lang/projectCache.ts", - "./main/lang/projectService.ts", - "./main/lang/transformers/implementations/nullTransformer.ts", - "./main/lang/transformers/transformer.ts", - "./main/lang/transformers/transformerRegistry.ts", - "./main/lang/typescriptServices.ts", - "./main/lang/utils.ts", - "./main/react/htmltotsx.ts", - "./main/tsconfig/dts-generator.ts", - "./main/tsconfig/formatting.ts", - "./main/tsconfig/simpleValidator.ts", - "./main/tsconfig/tsconfig.ts", - "./main/utils/fsUtil.ts", - "./typescript/makeTypeScriptGlobal.ts", - "./typings/atom/atom.d.ts", - "./typings/atompromise.d.ts", - "./typings/bluebird.d.ts", - "./typings/brackets.d.ts", - "./typings/codemirror.d.ts", - "./typings/d3/d3.d.ts", - "./typings/emissary/emissary.d.ts", - "./typings/htmltojsx/htmltojsx.d.ts", - "./typings/jquery/jquery.d.ts", - "./typings/minimatch/minimatch.d.ts", - "./typings/mixto/mixto.d.ts", - "./typings/mkdirp/mkdirp.d.ts", - "./typings/mustache.d.ts", - "./typings/q/Q.d.ts", - "./typings/react/react-jsx.d.ts", - "./typings/react/react.d.ts", - "./typings/space-pen/space-pen.d.ts", - "./typings/status-bar/status-bar.d.ts", - "./typings/text-buffer/text-buffer.d.ts", - "./typings/tsd.d.ts", - "./worker/child.ts", - "./worker/debug.ts", - "./worker/lib/workerLib.ts", - "./worker/parent.ts", - "./worker/queryParent.ts", - "./main/atom/views/rView.tsx", - "./main/atom/views/semanticView.tsx", - "../typings/main.d.ts" - ], - "exclude": [], - "atom": { - "rewriteTsconfig": true, - "formatOnSave": false - } + "compilerOptions": { + "forceConsistentCasingInFileNames": true, + "importHelpers": true, + "jsx": "react", + "lib": ["es6", "dom"], + "module": "commonjs", + "noLib": false, + "outDir": "../dist", + "preserveConstEnums": true, + "reactNamespace": "dom", + "skipLibCheck": true, + "sourceMap": true, + "strict": true, + "target": "es6" + }, + "compileOnSave": true, + "formatCodeOptions": { + "baseIndentSize": 0, + "indentSize": 2, + "tabSize": 2, + "newLineCharacter": "\n", + "convertTabsToSpaces": true, + "indentStyle": "Smart", + "insertSpaceAfterCommaDelimiter": true, + "insertSpaceAfterSemicolonInForStatements": false, + "insertSpaceBeforeAndAfterBinaryOperators": true, + "insertSpaceAfterConstructor": false, + "insertSpaceAfterKeywordsInControlFlowStatements": true, + "insertSpaceAfterFunctionKeywordForAnonymousFunctions": false, + "insertSpaceAfterOpeningAndBeforeClosingNonemptyParenthesis": false, + "insertSpaceAfterOpeningAndBeforeClosingNonemptyBrackets": false, + "insertSpaceAfterOpeningAndBeforeClosingNonemptyBraces": false, + "insertSpaceAfterOpeningAndBeforeClosingTemplateStringBraces": false, + "insertSpaceAfterOpeningAndBeforeClosingJsxExpressionBraces": false, + "insertSpaceBeforeFunctionParenthesis": false, + "placeOpenBraceOnNewLineForFunctions": false, + "placeOpenBraceOnNewLineForControlBlocks": false + } } diff --git a/lib/tsd.json b/lib/tsd.json deleted file mode 100644 index 908b7101c..000000000 --- a/lib/tsd.json +++ /dev/null @@ -1,51 +0,0 @@ -{ - "version": "v4", - "repo": "borisyankov/DefinitelyTyped", - "ref": "master", - "path": "typings", - "bundle": "typings/tsd.d.ts", - "installed": { - "emissary/emissary.d.ts": { - "commit": "69bdfb0884020e41f17a1dd80ad4c77de2636874" - }, - "mixto/mixto.d.ts": { - "commit": "69bdfb0884020e41f17a1dd80ad4c77de2636874" - }, - "atom/atom.d.ts": { - "commit": "69bdfb0884020e41f17a1dd80ad4c77de2636874" - }, - "text-buffer/text-buffer.d.ts": { - "commit": "69bdfb0884020e41f17a1dd80ad4c77de2636874" - }, - "status-bar/status-bar.d.ts": { - "commit": "69bdfb0884020e41f17a1dd80ad4c77de2636874" - }, - "space-pen/space-pen.d.ts": { - "commit": "69bdfb0884020e41f17a1dd80ad4c77de2636874" - }, - "jquery/jquery.d.ts": { - "commit": "69bdfb0884020e41f17a1dd80ad4c77de2636874" - }, - "q/Q.d.ts": { - "commit": "69bdfb0884020e41f17a1dd80ad4c77de2636874" - }, - "mkdirp/mkdirp.d.ts": { - "commit": "69bdfb0884020e41f17a1dd80ad4c77de2636874" - }, - "d3/d3.d.ts": { - "commit": "2520bce9a8a71b66e67487cbd5b33fec880b0c55" - }, - "react/react.d.ts": { - "commit": "6f04d25ad38982d372cc3cda62fa4c0eef9e24d7" - }, - "react/react-jsx.d.ts": { - "commit": "6f04d25ad38982d372cc3cda62fa4c0eef9e24d7" - }, - "htmltojsx/htmltojsx.d.ts": { - "commit": "1632606f82cfbaf89d4b96b8dccacfaf2a6ae2f3" - }, - "minimatch/minimatch.d.ts": { - "commit": "66f88ec51858bb21bc375fa91a963c04bc09401e" - } - } -} diff --git a/lib/typescript/makeTypeScriptGlobal.ts b/lib/typescript/makeTypeScriptGlobal.ts deleted file mode 100644 index 6404e9313..000000000 --- a/lib/typescript/makeTypeScriptGlobal.ts +++ /dev/null @@ -1,21 +0,0 @@ -import {isAbsolute} from "path" - -// Debugging helper -global.stack = function() { - console.error((new Error()).stack); -} - -// Export Typescript as a global. Takes an optional full path to typescriptServices.js -export function makeTsGlobal(typescriptPath?: string) { - if (typescriptPath) { - if (!isAbsolute(typescriptPath)) { - throw new Error(`Path to Typescript "${typescriptPath}" is not absolute`) - } - - typescriptPath = typescriptPath.trim() - } else { - typescriptPath = "typescript" - } - - global.ts = require(typescriptPath); -} diff --git a/lib/typescript/readme.md b/lib/typescript/readme.md deleted file mode 100644 index fbc68e1cf..000000000 --- a/lib/typescript/readme.md +++ /dev/null @@ -1,3 +0,0 @@ -# Magic -Basically we run `makeTypeScriptGlobal.ts` (both in parent and child) to export `module ts` to the variable `global.ts` so we can just use `ts.` without any imports. -This isn't ideal but it makes it easier to not have a `require('typescript')` all over the code base. Also it makes it easier to swap out `typescript` with something else (we sometimes move to nightly typescript `ntypescript`). Also you can point it to a custom typescript file if you want (we have a package option exposed to atom for this). \ No newline at end of file diff --git a/lib/typings/atom.d.ts b/lib/typings/atom.d.ts new file mode 100644 index 000000000..29c8f1b6c --- /dev/null +++ b/lib/typings/atom.d.ts @@ -0,0 +1,15 @@ +export {} + +declare module "atom" { + export class CompositeDisposable { + add(disposable: AtomCore.Disposable) + dispose() + } + + var TextBuffer: { + new (opts?: { + filePath?: string + load?: boolean + }): TextBuffer.ITextBuffer + } +} diff --git a/lib/typings/atom/atom.d.ts b/lib/typings/atom/atom.d.ts deleted file mode 100644 index c55c8f4ec..000000000 --- a/lib/typings/atom/atom.d.ts +++ /dev/null @@ -1,1759 +0,0 @@ -// Type definitions for Atom -// Project: https://atom.io/ -// Definitions by: vvakame -// Definitions: https://github.com/borisyankov/DefinitelyTyped - -/// -/// -/// -/// -/// -/// - -// Policy: this definition file only declare element related to `atom`. -// if js file include to another npm package (e.g. "space-pen", "mixto" and "emissary"). -// you should create a separate file. - -// NOTE Document? You should use DevTools hehe... - -interface Window { - atom: AtomCore.IAtom; - measure(description:string, fn:Function):any; // return fn result - profile(description:string, fn:Function):any; // return fn result -} - -declare module AtomCore { - -// https://atom.io/docs/v0.84.0/advanced/view-system - interface IWorkspaceViewStatic { - new ():IWorkspaceView; - - version: number; - configDefaults:any; - content():any; - } - - interface Disposable { - dispose(); - } - - interface Decoration - { - destroy(): void; - } - - /** - * Represents a buffer annotation that remains logically stationary even as the buffer changes. This is used - * to represent cursors, folds, snippet targets, misspelled words, any anything else that needs to track a - * logical location in the buffer over time. - */ - interface Marker { - /** - * Destroys the marker, causing it to emit the 'destroyed' event. Once destroyed, a marker cannot be - * restored by undo/redo operations. - */ - destroy(): void; - - /** - * Gets the screen range of the display marker. - */ - getScreenRange(): Range; - } - - interface IWorkspaceView extends View { - // Delegator.includeInto(WorkspaceView); - - // delegate to model property's property - fullScreen:boolean; - - // delegate to model property's method - open(uri:string, options:any):Q.Promise; - openSync(uri:string, options?:any):any; - saveActivePaneItem():any; - saveActivePaneItemAs():any; - saveAll():void; - destroyActivePaneItem():any; - destroyActivePane():any; - increaseFontSize():void; - decreaseFontSize():void; - - // own property & methods - initialize(model:IWorkspace):any; - initialize(view:View, args:any):void; // do not use - model:IWorkspace; - panes: IPaneContainerView; - getModel():IWorkspace; - installShellCommands():any; - handleFocus():any; - afterAttach(onDom?:any):any; - confirmClose():boolean; - updateTitle():any; - setTitle(title:string):any; - getEditorViews():any[]; // atom.EditorView - prependToTop(element:any):any; - appendToTop(element:any):any; - prependToBottom(element:any):any; - appendToBottom(element:any):any; - prependToLeft(element:any):any; - appendToLeft(element:any):any; - prependToRight(element:any):any; - appendToRight(element:any):any; - getActivePaneView():IPaneView; - getActiveView():View; - focusPreviousPaneView():any; - focusNextPaneView():any; - focusPaneViewAbove():any; - focusPaneViewBelow():any; - focusPaneViewOnLeft():any; - focusPaneViewOnRight():any; - eachPaneView(callback:(paneView:IPaneView)=>any):{ off():any; }; - getPaneViews():IPaneView[]; - eachEditorView(callback:(editorView:any /* EditorView */)=>any):{ off():any; }; - beforeRemove():any; - - command(eventName:string, handler:Function):any; - command(eventName:string, selector:Function, handler:Function):any; - command(eventName:string, options:any, handler:Function):any; - command(eventName:string, selector:Function, options:any, handler:Function):any; - - statusBar:StatusBar.IStatusBarView; - } - - interface IPanes { - // TBD - } - - interface IPaneView { - // TBD - } - - interface IPaneContainerView { - // TBD - } - - interface ITreeView { - // TBD - } - - interface IGutterViewStatic { - new(): IGutterView; - content():any; - } - - interface IGutterView extends View { - firstScreenRow:any; - lastScreenRow:any; - initialize():void; - initialize(view:View, args:any):void; // do not use - afterAttach(onDom?:any):any; - beforeRemove():any; - handleMouseEvents(e:JQueryMouseEventObject):any; - getEditorView():any; /* EditorView */ - getEditor():IEditor; - getLineNumberElements():HTMLCollection; - getLineNumberElementsForClass(klass:string):NodeList; - getLineNumberElement(bufferRow:number):NodeList; - addClassToAllLines(klass:string):boolean; - removeClassFromAllLines(klass:string):boolean; - addClassToLine(bufferRow:number, klass:string):boolean; - removeClassFromLine(bufferRow:number, klass:string):boolean; - updateLineNumbers(changes:any[], startScreenRow?:number, endScreenRow?:number):any; - prependLineElements(lineElements:any):void; - appendLineElements(lineElements:any):void; - removeLineElements(numberOfElements:number):void; - buildLineElements(startScreenRow:any, endScreenRow:any):any; - buildLineElementsHtml(startScreenRow:any, endScreenRow:any):any; - updateFoldableClasses(changes:any[]):any; - removeLineHighlights():void; - addLineHighlight(row:number, emptySelection?:boolean):any; - highlightLines():boolean; - } - - interface ICommandRegistry { - add(selector: string, name: string, callback: (event: any) => void); // selector:'atom-editor'|'atom-workspace' - dispatch(selector: any, name:string); - } - - interface ICommandPanel { - // TBD - } - - interface IDisplayBufferStatic { - new(_arg?:any):IDisplayBuffer; - } - - interface IDisplayBuffer /* extends Theorist.Model */ { - // Serializable.includeInto(Editor); - - constructor:IDisplayBufferStatic; - - verticalScrollMargin:number; - horizontalScrollMargin:number; - - declaredPropertyValues:any; - tokenizedBuffer: ITokenizedBuffer; - buffer: TextBuffer.ITextBuffer; - charWidthsByScope:any; - markers:{ [index:number]:IDisplayBufferMarker; }; - foldsByMarkerId:any; - maxLineLength:number; - screenLines:ITokenizedLine[]; - rowMap:any; // return type are RowMap - longestScreenRow:number; - subscriptions:Emissary.ISubscription[]; - subscriptionsByObject:any; // return type are WeakMap - behaviors:any; - subscriptionCounts:any; - eventHandlersByEventName:any; - pendingChangeEvent:any; - - softWrap:boolean; - - serializeParams():{id:number; softWrap:boolean; editorWidthInChars: number; scrollTop: number; scrollLeft: number; tokenizedBuffer: any; }; - deserializeParams(params:any):any; - copy():IDisplayBuffer; - updateAllScreenLines():any; - emitChanged(eventProperties:any, refreshMarkers?:boolean):any; - updateWrappedScreenLines():any; - setVisible(visible:any):any; - getVerticalScrollMargin():number; - setVerticalScrollMargin(verticalScrollMargin:number):number; - getHorizontalScrollMargin():number; - setHorizontalScrollMargin(horizontalScrollMargin:number):number; - getHeight():any; - setHeight(height:any):any; - getWidth():any; - setWidth(newWidth:any):any; - getScrollTop():number; - setScrollTop(scrollTop:number):number; - getScrollBottom():number; - setScrollBottom(scrollBottom:number):number; - getScrollLeft():number; - setScrollLeft(scrollLeft:number):number; - getScrollRight():number; - setScrollRight(scrollRight:number):number; - getLineHeight():any; - setLineHeight(lineHeight:any):any; - getDefaultCharWidth():any; - setDefaultCharWidth(defaultCharWidth:any):any; - getScopedCharWidth(scopeNames:any, char:any):any; - getScopedCharWidths(scopeNames:any):any; - setScopedCharWidth(scopeNames:any, char:any, width:any):any; - setScopedCharWidths(scopeNames:any, charWidths:any):any; - clearScopedCharWidths():any; - getScrollHeight():number; - getScrollWidth():number; - getVisibleRowRange():number[]; - intersectsVisibleRowRange(startRow:any, endRow:any):any; - selectionIntersectsVisibleRowRange(selection:any):any; - scrollToScreenRange(screenRange:any):any; - scrollToScreenPosition(screenPosition:any):any; - scrollToBufferPosition(bufferPosition:any):any; - pixelRectForScreenRange(screenRange:TextBuffer.IRange):any; - getTabLength():number; - setTabLength(tabLength:number):any; - setSoftWrap(softWrap:boolean):boolean; - getSoftWrap():boolean; - setEditorWidthInChars(editorWidthInChars:number):any; - getEditorWidthInChars():number; - getSoftWrapColumn():number; - lineForRow(row:number):any; - linesForRows(startRow:number, endRow:number):any; - getLines():any[]; - indentLevelForLine(line:any):any; - bufferRowsForScreenRows(startScreenRow:any, endScreenRow:any):any; - createFold(startRow:number, endRow:number):IFold; - isFoldedAtBufferRow(bufferRow:number):boolean; - isFoldedAtScreenRow(screenRow:number):boolean; - destroyFoldWithId(id:number):any; - unfoldBufferRow(bufferRow:number):any[]; - largestFoldStartingAtBufferRow(bufferRow:number):any; - foldsStartingAtBufferRow(bufferRow:number):any; - largestFoldStartingAtScreenRow(screenRow:any):any; - largestFoldContainingBufferRow(bufferRow:any):any; - outermostFoldsInBufferRowRange(startRow:any, endRow:any):any[]; - foldsContainingBufferRow(bufferRow:any):any[]; - screenRowForBufferRow(bufferRow:number):number; - lastScreenRowForBufferRow(bufferRow:number):number; - bufferRowForScreenRow(screenRow:number):number; - - screenRangeForBufferRange(bufferRange:TextBuffer.IPoint[]):TextBuffer.IRange; - - screenRangeForBufferRange(bufferRange:TextBuffer.IRange):TextBuffer.IRange; - - screenRangeForBufferRange(bufferRange:{start: TextBuffer.IPoint; end: TextBuffer.IPoint}):TextBuffer.IRange; - screenRangeForBufferRange(bufferRange:{start: number[]; end: TextBuffer.IPoint}):TextBuffer.IRange; - screenRangeForBufferRange(bufferRange:{start: {row:number; col:number;}; end: TextBuffer.IPoint}):TextBuffer.IRange; - - screenRangeForBufferRange(bufferRange:{start: TextBuffer.IPoint; end: number[]}):TextBuffer.IRange; - screenRangeForBufferRange(bufferRange:{start: number[]; end: number[]}):TextBuffer.IRange; - screenRangeForBufferRange(bufferRange:{start: {row:number; col:number;}; end: number[]}):TextBuffer.IRange; - - screenRangeForBufferRange(bufferRange:{start: TextBuffer.IPoint; end: {row:number; col:number;}}):TextBuffer.IRange; - screenRangeForBufferRange(bufferRange:{start: number[]; end: {row:number; col:number;}}):TextBuffer.IRange; - screenRangeForBufferRange(bufferRange:{start: {row:number; col:number;}; end: {row:number; col:number;}}):TextBuffer.IRange; - - bufferRangeForScreenRange(screenRange:TextBuffer.IPoint[]):TextBuffer.IRange; - - bufferRangeForScreenRange(screenRange:TextBuffer.IRange):TextBuffer.IRange; - - bufferRangeForScreenRange(screenRange:{start: TextBuffer.IPoint; end: TextBuffer.IPoint}):TextBuffer.IRange; - bufferRangeForScreenRange(screenRange:{start: number[]; end: TextBuffer.IPoint}):TextBuffer.IRange; - bufferRangeForScreenRange(screenRange:{start: {row:number; col:number;}; end: TextBuffer.IPoint}):TextBuffer.IRange; - - bufferRangeForScreenRange(screenRange:{start: TextBuffer.IPoint; end: number[]}):TextBuffer.IRange; - bufferRangeForScreenRange(screenRange:{start: number[]; end: number[]}):TextBuffer.IRange; - bufferRangeForScreenRange(screenRange:{start: {row:number; col:number;}; end: number[]}):TextBuffer.IRange; - - bufferRangeForScreenRange(screenRange:{start: TextBuffer.IPoint; end: {row:number; col:number;}}):TextBuffer.IRange; - bufferRangeForScreenRange(screenRange:{start: number[]; end: {row:number; col:number;}}):TextBuffer.IRange; - bufferRangeForScreenRange(screenRange:{start: {row:number; col:number;}; end: {row:number; col:number;}}):TextBuffer.IRange; - - pixelRangeForScreenRange(screenRange:TextBuffer.IPoint[], clip?:boolean):TextBuffer.IRange; - - pixelRangeForScreenRange(screenRange:TextBuffer.IRange, clip?:boolean):TextBuffer.IRange; - - pixelRangeForScreenRange(screenRange:{start: TextBuffer.IPoint; end: TextBuffer.IPoint}, clip?:boolean):TextBuffer.IRange; - pixelRangeForScreenRange(screenRange:{start: number[]; end: TextBuffer.IPoint}, clip?:boolean):TextBuffer.IRange; - pixelRangeForScreenRange(screenRange:{start: {row:number; col:number;}; end: TextBuffer.IPoint}, clip?:boolean):TextBuffer.IRange; - - pixelRangeForScreenRange(screenRange:{start: TextBuffer.IPoint; end: number[]}, clip?:boolean):TextBuffer.IRange; - pixelRangeForScreenRange(screenRange:{start: number[]; end: number[]}, clip?:boolean):TextBuffer.IRange; - pixelRangeForScreenRange(screenRange:{start: {row:number; col:number;}; end: number[]}, clip?:boolean):TextBuffer.IRange; - - pixelRangeForScreenRange(screenRange:{start: TextBuffer.IPoint; end: {row:number; col:number;}}, clip?:boolean):TextBuffer.IRange; - pixelRangeForScreenRange(screenRange:{start: number[]; end: {row:number; col:number;}}, clip?:boolean):TextBuffer.IRange; - pixelRangeForScreenRange(screenRange:{start: {row:number; col:number;}; end: {row:number; col:number;}}, clip?:boolean):TextBuffer.IRange; - - pixelPositionForScreenPosition(screenPosition:TextBuffer.IPoint, clip?:boolean):TextBuffer.IPoint; - pixelPositionForScreenPosition(screenPosition:number[], clip?:boolean):TextBuffer.IPoint; - pixelPositionForScreenPosition(screenPosition:{row:number; col:number;}, clip?:boolean):TextBuffer.IPoint; - - screenPositionForPixelPosition(pixelPosition:any):TextBuffer.IPoint; - - pixelPositionForBufferPosition(bufferPosition:any):any; - getLineCount():number; - getLastRow():number; - getMaxLineLength():number; - screenPositionForBufferPosition(bufferPosition:any, options:any):any; - bufferPositionForScreenPosition(bufferPosition:any, options:any):any; - scopesForBufferPosition(bufferPosition:any):any; - bufferRangeForScopeAtPosition(selector:any, position:any):any; - tokenForBufferPosition(bufferPosition:any):any; - getGrammar():IGrammar; - setGrammar(grammar:IGrammar):any; - reloadGrammar():any; - clipScreenPosition(screenPosition:any, options:any):any; - findWrapColumn(line:any, softWrapColumn:any):any; - rangeForAllLines():TextBuffer.IRange; - getMarker(id:number):IDisplayBufferMarker; - getMarkers():IDisplayBufferMarker[]; - getMarkerCount():number; - markScreenRange(range:TextBuffer.IRange, ...args:any[]):IDisplayBufferMarker; - markBufferRange(range:TextBuffer.IRange, options?:any):IDisplayBufferMarker; - markScreenPosition(screenPosition:TextBuffer.IPoint, options?:any):IDisplayBufferMarker; - markBufferPosition(bufferPosition:TextBuffer.IPoint, options?:any):IDisplayBufferMarker; - destroyMarker(id:number):any; - findMarker(params?:any):IDisplayBufferMarker; - findMarkers(params?:any):IDisplayBufferMarker[]; - translateToBufferMarkerParams(params?:any):any; - findFoldMarker(attributes:any):IMarker; - findFoldMarkers(attributes:any):IMarker[]; - getFoldMarkerAttributes(attributes?:any):any; - pauseMarkerObservers():any; - resumeMarkerObservers():any; - refreshMarkerScreenPositions():any; - destroy():any; - logLines(start:number, end:number):any[]; - handleTokenizedBufferChange(tokenizedBufferChange:any):any; - updateScreenLines(startBufferRow:any, endBufferRow:any, bufferDelta?:number, options?:any):any; - buildScreenLines(startBufferRow:any, endBufferRow:any):any; - findMaxLineLength(startScreenRow:any, endScreenRow:any, newScreenLines:any):any; - handleBufferMarkersUpdated():any; - handleBufferMarkerCreated(marker:any):any; - createFoldForMarker(maker:any):IFold; - foldForMarker(marker:any):any; - } - - interface IViewRegistry { - getView(selector:any):any; - } - - interface ICursorStatic { - new (arg:{editor:IEditor; marker:IDisplayBufferMarker; id: number;}):ICursor; - } - - interface ScopeDescriptor { - scopes: string[]; - } - - interface ICursor /* extends Theorist.Model */ { - getScopeDescriptor(): ScopeDescriptor; - screenPosition:any; - bufferPosition:any; - goalColumn:any; - visible:boolean; - needsAutoscroll:boolean; - - editor:IEditor; - marker:IDisplayBufferMarker; - id: number; - - destroy():any; - changePosition(options:any, fn:Function):any; - getPixelRect():any; - setScreenPosition(screenPosition:any, options?:any):any; - getScreenPosition():TextBuffer.IPoint; - getScreenRange():TextBuffer.IRange; - setBufferPosition(bufferPosition:any, options?:any):any; - getBufferPosition():TextBuffer.IPoint; - autoscroll():any; - updateVisibility():any; - setVisible(visible:boolean):any; - isVisible():boolean; - wordRegExp(arg?:any):any; - isLastCursor():boolean; - isSurroundedByWhitespace():boolean; - isBetweenWordAndNonWord():boolean; - isInsideWord():boolean; - clearAutoscroll():void; - clearSelection():void; - getScreenRow():number; - getScreenColumn():number; - getBufferRow():number; - getBufferColumn():number; - getCurrentBufferLine():string; - moveUp(rowCount:number, arg?:any):any; - moveDown(rowCount:number, arg?:any):any; - moveLeft(arg?:any):any; - moveRight(arg?:any):any; - moveToTop():any; - moveToBottom():void; - moveToBeginningOfScreenLine():void; - moveToBeginningOfLine():void; - moveToFirstCharacterOfLine():void; - moveToEndOfScreenLine():void; - moveToEndOfLine():void; - moveToBeginningOfWord():void; - moveToEndOfWord():void; - moveToBeginningOfNextWord():void; - moveToPreviousWordBoundary():void; - moveToNextWordBoundary():void; - getBeginningOfCurrentWordBufferPosition(options?:any):TextBuffer.IPoint; - getPreviousWordBoundaryBufferPosition(options?:any):TextBuffer.IPoint; - getMoveNextWordBoundaryBufferPosition(options?:any):TextBuffer.IPoint; - getEndOfCurrentWordBufferPosition(options?:any):TextBuffer.IPoint; - getBeginningOfNextWordBufferPosition(options?:any):TextBuffer.IPoint; - getCurrentWordBufferRange(options?:any):TextBuffer.IPoint; - getCurrentLineBufferRange(options?:any):TextBuffer.IPoint; - getCurrentParagraphBufferRange():any; - getCurrentWordPrefix():string; - isAtBeginningOfLine():boolean; - getIndentLevel():number; - isAtEndOfLine():boolean; - getScopes():string[]; - hasPrecedingCharactersOnLine():boolean; - getMarker(): Marker; - } - - interface ILanguageMode { - // TBD - } - - interface ISelection /* extends Theorist.Model */ { - cursor:ICursor; - marker:IDisplayBufferMarker; - editor:IEditor; - initialScreenRange:any; - wordwise:boolean; - needsAutoscroll:boolean; - retainSelection:boolean; - subscriptionCounts:any; - - destroy():any; - finalize():any; - clearAutoscroll():any; - isEmpty():boolean; - isReversed():boolean; - isSingleScreenLine():boolean; - getScreenRange():TextBuffer.IRange; - setScreenRange(screenRange:any, options:any):any; - getBufferRange():TextBuffer.IRange; - setBufferRange(bufferRange:any, options:any):any; - getBufferRowRange():number[]; - autoscroll():void; - getText():string; - clear():boolean; - selectWord():TextBuffer.IRange; - expandOverWord():any; - selectLine(row?:any):TextBuffer.IRange; - expandOverLine():boolean; - selectToScreenPosition(position:any):any; - selectToBufferPosition(position:any):any; - selectRight():boolean; - selectLeft():boolean; - selectUp(rowCount?:any):boolean; - selectDown(rowCount?:any):boolean; - selectToTop():any; - selectToBottom():any; - selectAll():any; - selectToBeginningOfLine():any; - selectToFirstCharacterOfLine():any; - selectToEndOfLine():any; - selectToBeginningOfWord():any; - selectToEndOfWord():any; - selectToBeginningOfNextWord():any; - selectToPreviousWordBoundary():any; - selectToNextWordBoundary():any; - addSelectionBelow():any; - getGoalBufferRange():any; - addSelectionAbove():any[]; - insertText(text:string, options?:any):any; - normalizeIndents(text:string, indentBasis:number):any; - indent(_arg?:any):any; - indentSelectedRows():TextBuffer.IRange[]; - setIndentationForLine(line:string, indentLevel:number):any; - backspace():any; - backspaceToBeginningOfWord():any; - backspaceToBeginningOfLine():any; - delete():any; - deleteToEndOfWord():any; - deleteSelectedText():any; - deleteLine():any; - joinLines():any; - outdentSelectedRows():any[]; - autoIndentSelectedRows():any; - toggleLineComments():any; - cutToEndOfLine(maintainClipboard:any):any; - cut(maintainClipboard:any):any; - copy(maintainClipboard:any):any; - fold():any; - modifySelection(fn:()=>any):any; - plantTail():any; - intersectsBufferRange(bufferRange:any):any; - intersectsWith(otherSelection:any):any; - merge(otherSelection:any, options:any):any; - compare(otherSelection:any):any; - getRegionRects():any[]; - screenRangeChanged():any; - } - - interface IEditor { - // Serializable.includeInto(Editor); - // Delegator.includeInto(Editor); - - deserializing:boolean; - callDisplayBufferCreatedHook:boolean; - registerEditor:boolean; - buffer:TextBuffer.ITextBuffer; - languageMode: ILanguageMode; - cursors:ICursor[]; - selections: ISelection[]; - suppressSelectionMerging:boolean; - softTabs: boolean; - displayBuffer: IDisplayBuffer; - - id:number; - behaviors:any; - declaredPropertyValues: any; - eventHandlersByEventName: any; - eventHandlersByNamespace: any; - lastOpened: number; - subscriptionCounts: any; - subscriptionsByObject: any; /* WeakMap */ - subscriptions: Emissary.ISubscription[]; - - serializeParams():{id:number; softTabs:boolean; scrollTop:number; scrollLeft:number; displayBuffer:any;}; - deserializeParams(params:any):any; - subscribeToBuffer():void; - subscribeToDisplayBuffer():void; - getViewClass():any; // return type are EditorView - isDestroyed():boolean; - copy():IEditor; - getTitle():string; - getLongTitle():string; - setVisible(visible:boolean):void; - setScrollTop(scrollTop:any):void; - getScrollTop():number; - setScrollLeft(scrollLeft:any):void; - getScrollLeft():number; - setEditorWidthInChars(editorWidthInChars:any):void; - getSoftWrapColumn():number; - getSoftTabs():boolean; - setSoftTabs(softTabs:boolean):void; - getSoftWrap():boolean; - setSoftWrap(softWrap:any):void; - getTabText():string; - getTabLength():number; - setTabLength(tabLength:any):void; - clipBufferPosition(bufferPosition:any):void; - clipBufferRange(range:any):void; - indentationForBufferRow(bufferRow:any):void; - setIndentationForBufferRow(bufferRow:any, newLevel:any, _arg:any):void; - indentLevelForLine(line:any):number; - buildIndentString(number:any):string; - save():void; - saveAs(filePath:any):void; - getPath():string; - getText():string; - setText(text:any):void; - getTextInRange(range:any):any; - getLineCount():number; - getBuffer():TextBuffer.ITextBuffer; - getUri():string; - isBufferRowBlank(bufferRow:any):boolean; - isBufferRowCommented(bufferRow:any):void; - nextNonBlankBufferRow(bufferRow:any):void; - getEofBufferPosition():TextBuffer.IPoint; - getLastBufferRow():number; - bufferRangeForBufferRow(row:any, options:any):TextBuffer.IRange; - lineForBufferRow(row:number):string; - lineLengthForBufferRow(row:number):number; - scan():any; - scanInBufferRange():any; - backwardsScanInBufferRange():any; - isModified():boolean; - shouldPromptToSave():boolean; - screenPositionForBufferPosition(bufferPosition:any, options?:any):TextBuffer.IPoint; - bufferPositionForScreenPosition(screenPosition:any, options?:any):TextBuffer.IPoint; - screenRangeForBufferRange(bufferRange:any):TextBuffer.IRange; - bufferRangeForScreenRange(screenRange:any):TextBuffer.IRange; - clipScreenPosition(screenPosition:any, options:any):TextBuffer.IRange; - lineForScreenRow(row:any):ITokenizedLine; - linesForScreenRows(start?:any, end?:any):ITokenizedLine[]; - getScreenLineCount():number; - getMaxScreenLineLength():number; - getLastScreenRow():number; - bufferRowsForScreenRows(startRow:any, endRow:any):any[]; - bufferRowForScreenRow(row:any):number; - scopesForBufferPosition(bufferPosition:any):string[]; - bufferRangeForScopeAtCursor(selector:string):any; - tokenForBufferPosition(bufferPosition:any):IToken; - insertText(text:string, options?:any):TextBuffer.IRange[]; - insertNewline():TextBuffer.IRange[]; - insertNewlineBelow():TextBuffer.IRange[]; - insertNewlineAbove():any; - indent(options?:any):any; - backspace():any[]; - backspaceToBeginningOfWord():any[]; - backspaceToBeginningOfLine():any[]; - delete():any[]; - deleteToEndOfWord():any[]; - deleteLine():TextBuffer.IRange[]; - indentSelectedRows():TextBuffer.IRange[][]; - outdentSelectedRows():TextBuffer.IRange[][]; - toggleLineCommentsInSelection():TextBuffer.IRange[]; - autoIndentSelectedRows():TextBuffer.IRange[][]; - normalizeTabsInBufferRange(bufferRange:any):any; - cutToEndOfLine():boolean[]; - cutSelectedText():boolean[]; - copySelectedText():boolean[]; - pasteText(options?:any):TextBuffer.IRange[]; - undo():any[]; - redo():any[]; - foldCurrentRow():any; - unfoldCurrentRow():any[]; - foldSelectedLines():any[]; - foldAll():any[]; - unfoldAll():any[]; - foldAllAtIndentLevel(level:any):any; - foldBufferRow(bufferRow:any):any; - unfoldBufferRow(bufferRow:any):any; - isFoldableAtBufferRow(bufferRow:any):boolean; - createFold(startRow:any, endRow:any):IFold; - destroyFoldWithId(id:any):any; - destroyFoldsIntersectingBufferRange(bufferRange:any):any; - toggleFoldAtBufferRow(bufferRow:any):any; - isFoldedAtCursorRow():boolean; - isFoldedAtBufferRow(bufferRow:any):boolean; - isFoldedAtScreenRow(screenRow:any):boolean; - largestFoldContainingBufferRow(bufferRow:any):boolean; - largestFoldStartingAtScreenRow(screenRow:any):any; - outermostFoldsInBufferRowRange(startRow:any, endRow:any):any[]; - moveLineUp():ISelection[]; - moveLineDown():ISelection[]; - duplicateLines():any[][]; - duplicateLine():any[][]; - mutateSelectedText(fn:(selection:ISelection)=>any):any; - replaceSelectedText(options:any, fn:(selection:string)=>any):any; - getMarker(id:number):IDisplayBufferMarker; - getMarkers():IDisplayBufferMarker[]; - findMarkers(...args:any[]):IDisplayBufferMarker[]; - markScreenRange(...args:any[]):IDisplayBufferMarker; - markBufferRange(...args:any[]):IDisplayBufferMarker; - markScreenPosition(...args:any[]):IDisplayBufferMarker; - markBufferPosition(...args:any[]):IDisplayBufferMarker; - destroyMarker(...args:any[]):boolean; - getMarkerCount():number; - hasMultipleCursors():boolean; - getCursors():ICursor[]; - addCursorAtScreenPosition(screenPosition:any):ICursor; - addCursorAtBufferPosition(bufferPosition:any):ICursor; - addCursor(marker:any):ICursor; - removeCursor(cursor:any):ICursor[]; - addSelection(marker:any, options:any):ISelection; - addSelectionForBufferRange(bufferRange:any, options:any):ISelection; - setSelectedBufferRange(bufferRange:any, options:any):any; - setSelectedBufferRanges(bufferRanges:any, options:any):any; - removeSelection(selection:ISelection):any; - clearSelections():boolean; - consolidateSelections():boolean; - getSelections():ISelection[]; - getSelection(index?:number):ISelection; - getLastSelection():ISelection; - getSelectionsOrderedByBufferPosition():ISelection[]; - getLastSelectionInBuffer():ISelection; - selectionIntersectsBufferRange(bufferRange:any):any; - setCursorScreenPosition(position:TextBuffer.IPoint, options?:any):any; - getCursorScreenPosition():TextBuffer.IPoint; - getCursorScreenRow():number; - setCursorBufferPosition(position:any, options?:any):any; - getCursorBufferPosition():TextBuffer.IPoint; - getSelectedScreenRange():TextBuffer.IRange; - getSelectedBufferRange():TextBuffer.IRange; - getSelectedBufferRanges():TextBuffer.IRange[]; - getSelectedText():string; - getTextInBufferRange(range:TextBuffer.IRange):string; - setTextInBufferRange(range:TextBuffer.IRange | any[], text:string):any; - getCurrentParagraphBufferRange():TextBuffer.IRange; - getWordUnderCursor(options?:any):string; - moveCursorUp(lineCount?:number):void; - moveCursorDown(lineCount?:number):void; - moveCursorLeft():void; - moveCursorRight():void; - moveCursorToTop():void; - moveCursorToBottom():void; - moveCursorToBeginningOfScreenLine():void; - moveCursorToBeginningOfLine():void; - moveCursorToFirstCharacterOfLine():void; - moveToEndOfScreenLine():void; - moveCursorToEndOfLine():void; - moveCursorToBeginningOfWord():void; - moveCursorToEndOfWord():void; - moveCursorToBeginningOfNextWord():void; - moveCursorToPreviousWordBoundary():void; - moveCursorToNextWordBoundary():void; - moveCursors(fn:(cursor:ICursor)=>any):any; - moveToBeginningOfLine():any; - moveToEndOfLine():any; - selectToScreenPosition(position:TextBuffer.IPoint):any; - selectRight():ISelection[]; - selectLeft():ISelection[]; - selectUp(rowCount?:number):ISelection[]; - selectDown(rowCount?:number):ISelection[]; - selectToTop():ISelection[]; - selectAll():ISelection[]; - selectToBottom():ISelection[]; - selectToBeginningOfLine():ISelection[]; - selectToFirstCharacterOfLine():ISelection[]; - selectToEndOfLine():ISelection[]; - selectToPreviousWordBoundary():ISelection[]; - selectToNextWordBoundary():ISelection[]; - selectLine():ISelection[]; - selectLinesContainingCursors():ISelection[]; - addSelectionBelow():ISelection[]; - addSelectionAbove():ISelection[]; - splitSelectionsIntoLines():any[]; - transpose():TextBuffer.IRange[]; - upperCase():boolean[]; - lowerCase():boolean[]; - joinLines():any[]; - selectToBeginningOfWord():ISelection[]; - selectToEndOfWord():ISelection[]; - selectToBeginningOfNextWord():ISelection[]; - selectWord():ISelection[]; - selectMarker(marker:any):any; - mergeCursors():number[]; - expandSelectionsForward():any; - expandSelectionsBackward(fn:(selection:ISelection)=>any):ISelection[]; - finalizeSelections():boolean[]; - mergeIntersectingSelections():any; - preserveCursorPositionOnBufferReload():Emissary.ISubscription; - getGrammar(): IGrammar; - setGrammar(grammer:IGrammar):void; - reloadGrammar():any; - shouldAutoIndent():boolean; - transact(fn:Function):any; - beginTransaction():ITransaction; - commitTransaction():any; - abortTransaction():any[]; - inspect():string; - logScreenLines(start:number, end:number):any[]; - handleGrammarChange():void; - handleMarkerCreated(marker:any):any; - getSelectionMarkerAttributes():{type: string; editorId: number; invalidate: string; }; - // joinLine():any; // deprecated - - observeGrammar(callback: Function): Disposable; - onDidChangeGrammar(callback: Function): Disposable; - onDidChange(callback: Function): Disposable; - onDidDestroy(callback: Function): Disposable; - onDidStopChanging(callback: Function): Disposable; - onDidChangeCursorPosition(callback: Function): Disposable; - onDidSave(callback: (event: { path: string }) => void): Disposable; - - screenPositionForPixelPosition: Function; - pixelPositionForBufferPosition: Function; - getHeight(): number; - - decorateMarker(marker: Marker, options: any): Decoration; - getLastCursor(): ICursor; - } - - interface IGrammar { - bundledPackage: boolean; - emitter: any; - fileTypes: [string]; - firstLineRegex: any; - foldingStopMarker: any; - includedGrammarScopes: [any]; - initialRule: any; - injectionSelector: any; - injections: any; - maxTokensPerLine: Number; - name: string; - packageName: string; - path: string; - rawPatterns: [any]; - rawRepository: any; - registration: Disposable; - registry: any; - repository: Object; - scopeName: string; - // TBD - - } - - interface IPane /* extends Theorist.Model */ { - itemForURI: (uri:string)=>IEditor; - items:any[]; - activeItem:any; - - serializeParams():any; - deserializeParams(params:any):any; - getViewClass():any; // return type are PaneView - isActive():boolean; - isDestroyed():boolean; - focus():void; - blur():void; - activate():void; - getPanes():IPane[]; - getItems():any[]; - getActiveItem():any; - getActiveEditor():any; - itemAtIndex(index:number):any; - activateNextItem():any; - activatePreviousItem():any; - getActiveItemIndex():number; - activateItemAtIndex(index:number):any; - activateItem(item:any):any; - addItem(item:any, index:number):any; - addItems(items:any[], index:number):any[]; - removeItem(item:any, destroying:any):void; - moveItem(item:any, newIndex:number):void; - moveItemToPane(item:any, pane:IPane, index:number):void; - destroyActiveItem():boolean; // always return false - destroyItem(item:any):boolean; - destroyItems():any[]; - destroyInactiveItems():any[]; - destroy():void; - destroyed():any[]; - promptToSaveItem(item:any):boolean; - saveActiveItem():void; - saveActiveItemAs():void; - saveItem(item:any, nextAction:Function):void; - saveItemAs(item:any, nextAction:Function):void; - saveItems():any[]; - itemForUri(uri:any):any; - activateItemForUri(uri:any):any; - copyActiveItem():void; - splitLeft(params:any):IPane; - splitRight(params:any):IPane; - splitUp(params:any):IPane; - splitDown(params:any):IPane; - split(orientation:string, side:string, params:any):IPane; - findLeftmostSibling():IPane; - findOrCreateRightmostSibling():IPane; - } - -// https://atom.io/docs/v0.84.0/advanced/serialization - interface ISerializationStatic { - deserialize(data:ISerializationInfo):T; - new (data:T): ISerialization; - } - - interface ISerialization { - serialize():ISerializationInfo; - } - - interface ISerializationInfo { - deserializer: string; - } - - interface IBrowserWindow { - getPosition():number[]; - getSize():number[]; - } - - interface IAtomWindowDimentions { - x:number; - y:number; - width:number; - height:number; - } - - interface IProjectStatic { - pathForRepositoryUrl(repoUrl:string):string; - - new (arg?:{path:any; buffers:any[];}):IProject; - } - - interface IProject /* extends Theorist.Model */ { - // Serializable.includeInto(Project); - - path:string; - /** deprecated */ - rootDirectory?:PathWatcher.IDirectory; - rootDirectories:PathWatcher.IDirectory[]; - - serializeParams():any; - deserializeParams(params:any):any; - destroyed():any; - destroyRepo():any; - destroyUnretainedBuffers():any; - getRepo():IGit; - getPath():string; - setPath(projectPath:string):any; - getRootDirectory():PathWatcher.IDirectory; - resolve(uri:string):string; - relativize(fullPath:string):string; - contains(pathToCheck:string):boolean; - open(filePath:string, options?:any):Q.Promise; - openSync(filePath:string, options?:any):IEditor; - getBuffers():TextBuffer.ITextBuffer; - isPathModified(filePath:string):boolean; - findBufferForPath(filePath:string):TextBuffer.ITextBuffer; - bufferForPathSync(filePath:string):TextBuffer.ITextBuffer; - bufferForPath(filePath:string):Q.Promise; - bufferForId(id:any):TextBuffer.ITextBuffer; - buildBufferSync(absoluteFilePath:string):TextBuffer.ITextBuffer; - buildBuffer(absoluteFilePath:string):Q.Promise; - addBuffer(buffer:TextBuffer.ITextBuffer, options?:any):any; - addBufferAtIndex(buffer:TextBuffer.ITextBuffer, index:number, options?:any):any; - scan(regex:any, options:any, iterator:any):Q.Promise; - replace(regex:any, replacementText:any, filePaths:any, iterator:any):Q.Promise; - buildEditorForBuffer(buffer:any, editorOptions:any):IEditor; - eachBuffer(...args:any[]):any; - - onDidChangePaths(callback: Function): Disposable; - } - - interface IWorkspaceStatic { - new():IWorkspace; - } - - interface IWorkspacePanelOptions{ - item:any; - visible?:boolean; - priority?:number; - } - - interface Panel{ - getItem():any; - getPriority():any; - isVisible():boolean; - show(); - hide(); - } - - interface IWorkspace { - addBottomPanel(options:IWorkspacePanelOptions):Panel; - addLeftPanel(options:IWorkspacePanelOptions):Panel; - addRightPanel(options:IWorkspacePanelOptions):Panel; - addTopPanel(options:IWorkspacePanelOptions):Panel; - addModalPanel(options:IWorkspacePanelOptions):Panel; - addOpener(opener: Function): any; - - deserializeParams(params:any):any; - serializeParams():{paneContainer:any;fullScreen:boolean;}; - eachEditor(callback: Function): void; - getTextEditors():IEditor[]; - open(uri:string, options:any):Q.Promise; - openLicense():void; - openSync(uri:string, options:any):any; - openUriInPane(uri: string, pane: any, options: any): Q.Promise; - observeTextEditors(callback: Function): Disposable; - reopenItemSync():any; - registerOpener(opener:(urlToOpen:string)=>any):void; - unregisterOpener(opener:Function):void; - getOpeners():any; - getActivePane(): IPane; - getActivePaneItem(): IPane; - getActiveTextEditor(): IEditor; - getPanes():any; - saveAll():void; - activateNextPane():any; - activatePreviousPane():any; - paneForURI: (uri:string) => IPane; - saveActivePaneItem():any; - saveActivePaneItemAs():any; - destroyActivePaneItem():any; - destroyActivePane():any; - increaseFontSize():void; - decreaseFontSize():void; - resetFontSize():void; - itemOpened(item:any):void; - onPaneItemDestroyed(item:any):void; - destroyed():void; - - onDidChangeActivePaneItem(item:any):Disposable; - } - - interface IAtomSettings { - appVersion: string; - bootstrapScript: string; - devMode: boolean; - initialPath: string; - pathToOpen: string; - resourcePath: string; - shellLoadTime: number; - windowState:string; - } - - interface IAtomState { - mode:string; - packageStates:any; - project:any; - syntax:any; - version:number; - windowDimensions:any; - workspace:any; - } - - interface IDeserializerManager { - deserializers:Function; - add:Function; - remove:Function; - deserialize:Function; - get:Function; - } - - interface IConfig { - get(keyPath:string):any; - set(keyPath:string, value:any):any; - // TBD - } - - interface IKeymapManager { - defaultTarget:HTMLElement; - // TBD - } - - interface IPackageManager extends Emissary.IEmitter { - packageDirPaths:string[]; - loadedPackages:any; - activePackages:any; - packageStates:any; - packageActivators:any[]; - - getApmPath():string; - getPackageDirPaths():string; - getPackageState(name:string):any; - setPackageState(name:string, state:any):void; - enablePackage(name:string):any; - disablePackage(name:string):any; - activate():void; - registerPackageActivator(activator:any, types:any):void; - activatePackages(packages:any):void; - activatePackage(name:string):any; - deactivatePackages():void; - deactivatePackage(name:string):void; - getActivePackages():any; - getActivePackage(name:string):any; - isPackageActive(name:string):boolean; - unobserveDisabledPackages():void; - observeDisabledPackages():void; - loadPackages():void; - loadPackage(nameOrPath:string):void; - unloadPackages():void; - unloadPackage(name:string):void; - getLoadedPackage(name:string):any; - isPackageLoaded(name:string):boolean; - getLoadedPackages():any; - getLoadedPackagesForTypes(types:any):any[]; - resolvePackagePath(name:string):string; - isPackageDisabled(name:string):boolean; - hasAtomEngine(packagePath:string):boolean; - isBundledPackage(name:string):boolean; - getPackageDependencies():any; - getAvailablePackagePaths():any[]; - getAvailablePackageNames():any[]; - getAvailablePackageMetadata():any[]; - } - - interface INotifications { - addInfo: Function; - addError: Function; - addSuccess: Function; - addWarning: Function; - } - - interface IThemeManager { - // TBD - } - - interface IContextMenuManager { - // TBD - } - - interface IMenuManager { - // TBD - } - - interface IClipboard { - write(text:string, metadata?:any):any; - read():string; - } - - interface ISyntax { - // TBD - } - - interface IWindowEventHandler { - // TBD - } - - interface IAtomStatic extends ISerializationStatic { - version: number; - loadSettings: IAtomSettings; - loadOrCreate(mode:string):IAtom; - loadState(mode:any):void; - getStatePath(mode:any):string; - getConfigDirPath():string; - getStorageDirPath():string; - getLoadSettings():IAtomSettings; - getCurrentWindow():IBrowserWindow; - getVersion():string; - isReleasedVersion():boolean; - - new(state:IAtomState):IAtom; - } - - interface IAtom { - constructor:IAtomStatic; - - state:IAtomState; - mode:string; - deserializers:IDeserializerManager; - config: IConfig; - commands: ICommandRegistry; - keymaps: IKeymapManager; - keymap: IKeymapManager; - packages: IPackageManager; - themes: IThemeManager; - contextManu: IContextMenuManager; - menu: IMenuManager; - notifications: INotifications; // https://github.com/atom/notifications - clipboard:IClipboard; - syntax:ISyntax; - views: IViewRegistry; - windowEventHandler: IWindowEventHandler; - - // really exists? start - subscribe:Function; - unsubscribe:Function; - loadTime:number; - workspaceViewParentSelector:string; - - project: IProject; - workspaceView: IWorkspaceView; - workspace: IWorkspace; - // really exists? end - - initialize:Function; - // registerRepresentationClass:Function; - // registerRepresentationClasses:Function; - setBodyPlatformClass:Function; - getCurrentWindow():IBrowserWindow; - getWindowDimensions:Function; - setWindowDimensions:Function; - restoreWindowDimensions:Function; - storeWindowDimensions:Function; - getLoadSettings:Function; - deserializeProject: Function; - deserializeWorkspaceView:Function; - deserializePackageStates:Function; - deserializeEditorWindow:Function; - startEditorWindow:Function; - unloadEditorWindow:Function; - loadThemes:Function; - watchThemes:Function; - open:Function; - confirm:Function; - showSaveDialog:Function; - showSaveDialogSync:Function; - openDevTools:Function; - toggleDevTools:Function; - executeJavaScriptInDevTools:Function; - reload:Function; - focus:Function; - show:Function; - hide:Function; - setSize:Function; - setPosition:Function; - center:Function; - displayWindow:Function; - close:Function; - exit:Function; - inDevMode:Function; - inSpecMode:Function; - toggleFullScreen:Function; - setFullScreen:Function; - isFullScreen:Function; - getVersion:Function; - isReleasedVersion:Function; - getGitHubAuthTokenName:Function; - setGitHubAuthToken:Function; - getGitHubAuthToken:Function; - getConfigDirPath:Function; - saveSync:Function; - getWindowLoadTime():number; - crashMainProcess:Function; - crashRenderProcess:Function; - beep:Function; - getUserInitScriptPath:Function; - requireUserInitScript:Function; - requireWithGlobals: Function; - - services: any; // TODO: New services api - } - - interface IBufferedNodeProcessStatic { - new (arg:any):IBufferedNodeProcess; - } - - interface IBufferedNodeProcess extends IBufferedProcess { - } - - interface IBufferedProcessStatic { - new (arg:any):IBufferedProcess; - } - - interface IBufferedProcess { - process:Function; - killed:boolean; - - bufferStream:Function; - kill:Function; - } - - interface IGitStatic { - new(path:any, options:any):IGit; - } - - interface IGit { - } - - interface ITokenizedBuffer { - // TBD - } - - interface ITokenizedLine { - // TBD - } - - interface IToken { - // TBD - } - - interface IFoldStatic { - new (displayBuffer:IDisplayBuffer, marker:IMarker):IFold; - // TBD - } - - interface IFold { - id:number; - displayBuffer:IDisplayBuffer; - marker:IMarker; - - // TBD - } - - interface IDisplayBufferMarkerStatic { - new (_arg:{bufferMarker:IMarker; displayBuffer: IDisplayBuffer}):IDisplayBufferMarker; - } - - interface IDisplayBufferMarker extends Emissary.IEmitter, Emissary.ISubscriber { - constructor:IDisplayBufferMarkerStatic; - - id: number; - - bufferMarkerSubscription:any; - oldHeadBufferPosition:TextBuffer.IPoint; - oldHeadScreenPosition:TextBuffer.IPoint; - oldTailBufferPosition:TextBuffer.IPoint; - oldTailScreenPosition:TextBuffer.IPoint; - wasValid:boolean; - - bufferMarker: IMarker; - displayBuffer: IDisplayBuffer; - globalPauseCount:number; - globalQueuedEvents:any; - - subscriptions:Emissary.ISubscription[]; - subscriptionsByObject:any; // WeakMap - - copy(attributes?:any /* maybe IMarker */):IDisplayBufferMarker; - getScreenRange():TextBuffer.IRange; - setScreenRange(screenRange:any, options:any):any; - getBufferRange():TextBuffer.IRange; - setBufferRange(bufferRange:any, options:any):any; - getPixelRange():any; - getHeadScreenPosition():TextBuffer.IPoint; - setHeadScreenPosition(screenPosition:any, options:any):any; - getHeadBufferPosition():TextBuffer.IPoint; - setHeadBufferPosition(bufferPosition:any):any; - getTailScreenPosition():TextBuffer.IPoint; - setTailScreenPosition(screenPosition:any, options:any):any; - getTailBufferPosition():TextBuffer.IPoint; - setTailBufferPosition(bufferPosition:any):any; - plantTail():boolean; - clearTail():boolean; - hasTail():boolean; - isReversed():boolean; - isValid():boolean; - isDestroyed():boolean; - getAttributes():any; - setAttributes(attributes:any):any; - matchesAttributes(attributes:any):any; - destroy():any; - isEqual(other:IDisplayBufferMarker):boolean; - compare(other:IDisplayBufferMarker):boolean; - inspect():string; - destroyed():any; - notifyObservers(_arg:any):any; - } - - interface ITransaction { - // TBD - } - - interface IMarker extends Emissary.IEmitter { - // Serializable.includeInto(Editor); - // Delegator.includeInto(Editor); - - // TBD - } - - interface ITaskStatic { - new(taskPath:any):ITask; - } - - interface ITask { - // TBD - } -} - -declare var atom:AtomCore.IAtom; - -declare module "atom" { - import spacePen = require("space-pen"); - - var $:typeof spacePen.$; - var $$:typeof spacePen.$$; - var $$$:typeof spacePen.$$$; - - var BufferedNodeProcess:AtomCore.IBufferedNodeProcessStatic; - var BufferedProcess:AtomCore.IBufferedProcessStatic; - var Git:AtomCore.IGitStatic; - var Point:TextBuffer.IPointStatic; - var Range:TextBuffer.IRangeStatic; - - class View extends spacePen.View implements Emissary.ISubscriber { - // Subscriber.includeInto(spacePen.View); - - // inherit from Subscriber - subscribeWith(eventEmitter:any, methodName:string, args:any):any; - - addSubscription(subscription:any):any; - - subscribe(eventEmitterOrSubscription:any, ...args:any[]):any; - - subscribeToCommand(eventEmitter:any, ...args:any[]):any; - - unsubscribe(object?:any):any; - } - - class EditorView extends View { - static characterWidthCache:any; - static configDefaults:any; - static nextEditorId:number; - - static content(params:any):void; - - static classes(_arg?:{mini?:any}):string; - - vScrollMargin:number; - hScrollMargin:number; - lineHeight:any; - charWidth:any; - charHeight:any; - cursorViews:any[]; - selectionViews:any[]; - lineCache:any[]; - isFocused:any; - editor:AtomCore.IEditor; - attached:any; - lineOverdraw:number; - pendingChanges:any[]; - newCursors:any[]; - newSelections:any[]; - redrawOnReattach:any; - bottomPaddingInLines:number; - active:boolean; - - id:number; - - gutter:AtomCore.IGutterView; - overlayer:JQuery; - scrollView:JQuery; - renderedLines:JQuery; - underlayer:JQuery; - hiddenInput:JQuery; - verticalScrollbar:JQuery; - verticalScrollbarContent:JQuery; - - constructor(editor:AtomCore.IEditor); - - initialize(editorOrOptions:AtomCore.IEditor):void; // return type are same as editor method. - initialize(editorOrOptions?:{editor: AtomCore.IEditor; mini:any; placeholderText:any}):void; - - initialize(editorOrOptions:{}):void; // compatible for spacePen.View - - bindKeys():void; - - getEditor():AtomCore.IEditor; - - getText():string; - - setText(text:string):void; - - insertText(text:string, options?:any):TextBuffer.IRange[]; - - setHeightInLines(heightInLines:number):number; - - setWidthInChars(widthInChars:number):number; - - pageDown():void; - - pageUp():void; - - getPageRows():number; - - setShowInvisibles(showInvisibles:boolean):void; - - setInvisibles(invisibles:{ eol:string; space: string; tab: string; cr: string; }):void; - - setShowIndentGuide(showIndentGuide:boolean):void; - - setPlaceholderText(placeholderText:string):void; - - getPlaceholderText():string; - - checkoutHead():boolean; - - configure():Emissary.ISubscription; - - handleEvents():void; - - handleInputEvents():void; - - bringHiddenInputIntoView():JQuery; - - selectOnMousemoveUntilMouseup():any; - - afterAttach(onDom:any):any; - - edit(editor:AtomCore.IEditor):any; - - getModel():AtomCore.IEditor; - - setModel(editor:AtomCore.IEditor):any; - - showBufferConflictAlert(editor:AtomCore.IEditor):any; - - scrollTop(scrollTop:number, options?:any):any; - - scrollBottom(scrollBottom?:number):any; - - scrollLeft(scrollLeft?:number):number; - - scrollRight(scrollRight?:number):any; - - scrollToBottom():any; - - scrollToCursorPosition():any; - - scrollToBufferPosition(bufferPosition:any, options:any):any; - - scrollToScreenPosition(screenPosition:any, options:any):any; - - scrollToPixelPosition(pixelPosition:any, options:any):any; - - highlightFoldsContainingBufferRange(bufferRange:any):any; - - saveScrollPositionForEditor():any; - - toggleSoftTabs():any; - - toggleSoftWrap():any; - - calculateWidthInChars():number; - - calculateHeightInLines():number; - - getScrollbarWidth():number; - - setSoftWrap(softWrap:boolean):any; - - setFontSize(fontSize:number):any; - - getFontSize():number; - - setFontFamily(fontFamily?:string):any; - - getFontFamily():string; - - setLineHeight(lineHeight:number):any; - - redraw():any; - - splitLeft():any; - - splitRight():any; - - splitUp():any; - - splitDown():any; - - getPane():any; // return type are PaneView - - remove(selector:any, keepData:any):any; - - beforeRemove():any; - - getCursorView(index?:number):any; // return type are CursorView - - getCursorViews():any[]; // return type are CursorView[] - - addCursorView(cursor:any, options:any):any; // return type are CursorView - - removeCursorView(cursorView:any):any; - - getSelectionView(index?:number):any; // return type are SelectionView - - getSelectionViews():any[]; // return type are SelectionView[] - - addSelectionView(selection:any):any; - - removeSelectionView(selectionView:any):any; - - removeAllCursorAndSelectionViews():any[]; - - appendToLinesView(view:any):any; - - scrollVertically(pixelPosition:any, _arg:any):any; - - scrollHorizontally(pixelPosition:any):any; - - calculateDimensions():number; - - recalculateDimensions():any; - - updateLayerDimensions():any; - - isHidden():boolean; - - clearRenderedLines():void; - - resetDisplay():any; - - requestDisplayUpdate():any; - - updateDisplay(options?:any):any; - - updateCursorViews():any; - - shouldUpdateCursor(cursorView:any):any; - - updateSelectionViews():any[]; - - shouldUpdateSelection(selectionView:any):any; - - syncCursorAnimations():any[]; - - autoscroll(suppressAutoscroll?:any):any[]; - - updatePlaceholderText():any; - - updateRenderedLines(scrollViewWidth:any):any; - - computeSurroundingEmptyLineChanges(change:any):any; - - computeIntactRanges(renderFrom:any, renderTo:any):any; - - truncateIntactRanges(intactRanges:any, renderFrom:any, renderTo:any):any; - - clearDirtyRanges(intactRanges:any):any; - - clearLine(lineElement:any):any; - - fillDirtyRanges(intactRanges:any, renderFrom:any, renderTo:any):any; - - updatePaddingOfRenderedLines():any; - - getFirstVisibleScreenRow():number; - - getLastVisibleScreenRow():number; - - isScreenRowVisible():boolean; - - handleScreenLinesChange(change:any):any; - - buildLineElementForScreenRow(screenRow:any):any; - - buildLineElementsForScreenRows(startRow:any, endRow:any):any; - - htmlForScreenRows(startRow:any, endRow:any):any; - - htmlForScreenLine(screenLine:any, screenRow:any):any; - - buildIndentation(screenRow:any, editor:any):any; - - buildHtmlEndOfLineInvisibles(screenLine:any):any; - - getEndOfLineInvisibles(screenLine:any):any; - - lineElementForScreenRow(screenRow:any):any; - - toggleLineCommentsInSelection():any; - - pixelPositionForBufferPosition(position:any):any; - - pixelPositionForScreenPosition(position:any):any; - - positionLeftForLineAndColumn(lineElement:any, screenRow:any, screenColumn:any):any; - - measureToColumn(lineElement:any, tokenizedLine:any, screenColumn:any):any; - - getCharacterWidthCache(scopes:any, char:any):any; - - setCharacterWidthCache(scopes:any, char:any, val:any):any; - - clearCharacterWidthCache():any; - - pixelOffsetForScreenPosition(position:any):any; - - screenPositionFromMouseEvent(e:any):any; - - highlightCursorLine():any; - - copyPathToClipboard():any; - - buildLineHtml(_arg:any):any; - - updateScopeStack(line:any, scopeStack:any, desiredScopes:any):any; - - pushScope(line:any, scopeStack:any, scope:any):any; - - popScope(line:any, scopeStack:any):any; - - buildEmptyLineHtml(showIndentGuide:any, eolInvisibles:any, htmlEolInvisibles:any, indentation:any, editor:any, mini:any):any; - - replaceSelectedText(replaceFn:(str:string)=>string):any; - - consolidateSelections(e:any):any; - - logCursorScope():any; - - logScreenLines(start:any, end:any):any; - - logRenderedLines():any; - } - - class ScrollView extends View { - // TBD - } - - interface ISelectListItem { - /** e.g. application:about */ - eventName:string; - /** e.g. Application: About */ - eventDescription:string; - } - - class SelectListView extends View { - static content():any; - - maxItems:number; - scheduleTimeout:any; - inputThrottle:number; - cancelling:boolean; - items:any[]; - list:JQuery; - filterEditorView: JQuery; - - previouslyFocusedElement:JQuery; - - initialize():any; - - schedulePopulateList():number; - - setItems(items:any[]):any; - - setError(message?:string):any; - - setLoading(message?:string):any; - - getFilterQuery():string; - - populateList():any; - - getEmptyMessage(itemCount?:any, filteredItemCount?:any):string; - - setMaxItems(maxItems:number):void; - - selectPreviousItemView():any; - - selectNextItemView():any; - - selectItemView(view:any):any; - - scrollToItemView(view:any):any; - - getSelectedItemView():any; - - getSelectedItem():any; - - confirmSelection():any; - - viewForItem(item:any):JQuery|string|HTMLElement|View; // You must override this method! - confirmed(item:any):any; // You must override this method! - getFilterKey():any; - - focusFilterEditor():any; - - storeFocusedElement():any; - - restoreFocus():any; - - cancelled():any; - - cancel():any; - } - - var WorkspaceView:AtomCore.IWorkspaceViewStatic; - - var Task:AtomCore.ITaskStatic; - var Workspace:AtomCore.IWorkspaceStatic; -} diff --git a/lib/typings/atom_core.d.ts b/lib/typings/atom_core.d.ts new file mode 100644 index 000000000..8bf45708c --- /dev/null +++ b/lib/typings/atom_core.d.ts @@ -0,0 +1,34 @@ +declare namespace AtomCore { + interface IEditor { + onDidChangeGrammar(callback: (grammar: IGrammar) => any): Disposable + } + interface IConfig { + onDidChange(opt: string, callback: (val: {oldValue: any, newValue: any}) => void): Disposable + } + interface CommandEvent extends Event { + abortKeyBinding(): any + } +} + +declare namespace TextBuffer { + interface ITextBuffer { + onWillChange(callback: Function): AtomCore.Disposable + onDidChange(callback: Function): AtomCore.Disposable + onDidChangeText(callback: Function): AtomCore.Disposable + onDidStopChanging(callback: Function): AtomCore.Disposable + onDidConflict(callback: Function): AtomCore.Disposable + onDidChangeModified(callback: Function): AtomCore.Disposable + onDidUpdateMarkers(callback: Function): AtomCore.Disposable + onDidCreateMarker(callback: Function): AtomCore.Disposable + onDidChangePath(callback: Function): AtomCore.Disposable + onDidChangeEncoding(callback: Function): AtomCore.Disposable + onWillSave(callback: Function): AtomCore.Disposable + onDidSave(callback: Function): AtomCore.Disposable + onDidDelete(callback: Function): AtomCore.Disposable + onWillReload(callback: Function): AtomCore.Disposable + onDidReload(callback: Function): AtomCore.Disposable + onDidDestroy(callback: Function): AtomCore.Disposable + onWillThrowWatchError(callback: Function): AtomCore.Disposable + scheduleDidStopChangingEvent() + } +} diff --git a/lib/typings/atompromise.d.ts b/lib/typings/atompromise.d.ts deleted file mode 100644 index 7c22e7b9d..000000000 --- a/lib/typings/atompromise.d.ts +++ /dev/null @@ -1,99 +0,0 @@ -// Ripped from lib.es6.d.ts with addtions for atom - -/** - * Represents the completion of an asynchronous operation - */ -interface Promise { - /** - * Attaches callbacks for the resolution and/or rejection of the Promise. - * @param onfulfilled The callback to execute when the Promise is resolved. - * @param onrejected The callback to execute when the Promise is rejected. - * @returns A Promise for the completion of which ever callback is executed. - */ - then(onfulfilled?: (value: T) => TResult | Promise, onrejected?: (reason: any) => TResult | Promise): Promise; - - /** - * Attaches a callback for only the rejection of the Promise. - * @param onrejected The callback to execute when the Promise is rejected. - * @returns A Promise for the completion of the callback. - */ - catch(onrejected?: (reason: any) => T | Promise): Promise; -} - -interface PromiseConstructor { - /** - * A reference to the prototype. - */ - prototype: Promise; - - /** - * Creates a new Promise. - * @param init A callback used to initialize the promise. This callback is passed two arguments: - * a resolve callback used resolve the promise with a value or the result of another promise, - * and a reject callback used to reject the promise with a provided reason or error. - */ - new (init: (resolve: (value?: T | Promise) => void, reject: (reason?: any) => void) => void): Promise; - - (init: (resolve: (value?: T | Promise) => void, reject: (reason?: any) => void) => void): Promise; - - /** - * Creates a Promise that is resolved with an array of results when all of the provided Promises - * resolve, or rejected when any Promise is rejected. - * @param values An array of Promises. - * @returns A new Promise. - */ - all(values: (T | Promise)[]): Promise; - - /** - * Creates a Promise that is resolved with an array of results when all of the provided Promises - * resolve, or rejected when any Promise is rejected. - * @param values An array of values. - * @returns A new Promise. - */ - all(values: Promise[]): Promise; - - /** - * Creates a Promise that is resolved or rejected when any of the provided Promises are resolved - * or rejected. - * @param values An array of Promises. - * @returns A new Promise. - */ - race(values: (T | Promise)[]): Promise; - - /** - * Creates a new rejected promise for the provided reason. - * @param reason The reason the promise was rejected. - * @returns A new rejected Promise. - */ - reject(reason: any): Promise; - - /** - * Creates a new rejected promise for the provided reason. - * @param reason The reason the promise was rejected. - * @returns A new rejected Promise. - */ - reject(reason: any): Promise; - - /** - * Creates a new resolved promise for the provided value. - * @param value A promise. - * @returns A promise whose internal state matches the provided promise. - */ - resolve(value: T | Promise): Promise; - - /** - * Creates a new resolved promise . - * @returns A resolved promise. - */ - resolve(): Promise; -} - -interface PromiseDeferred { - promise: Promise; resolve(value: T): any; reject(error: T): any; -} - -declare var Promise: PromiseConstructor; - -declare module 'pinkie-promise'{ - export = Promise; -} diff --git a/lib/typings/autocomplete.d.ts b/lib/typings/autocomplete.d.ts new file mode 100644 index 000000000..81b951bcd --- /dev/null +++ b/lib/typings/autocomplete.d.ts @@ -0,0 +1,50 @@ +/** What gets passed into the handler */ +export interface RequestOptions { + activatedManually: boolean + editor: AtomCore.IEditor + bufferPosition: TextBuffer.IPoint // the position of the cursor + prefix: string + scopeDescriptor: { scopes: string[] } +} + +/** The suggestion */ +export interface Suggestion { + // Either text or snippet is required + text?: string + snippet?: string + + displayText?: string + iconHTML?: string + + // The contents of the editor right before the cursor that are going to be replaced + replacementPrefix?: string + + // Left and right labels to show in the dropdown and their HTML versions + rightLabel?: string + rightLabelHTML?: string + leftLabel?: string + leftLabelHTML?: string + + type: string + + // Extra information shown at the bottom of the autocomplete dropdown for documentation, etc + description?: string + descriptionMoreURL?: string +} + +/** What the provider needs to implement */ +export interface Provider { + inclusionPriority?: number + excludeLowerPriority?: boolean + suggestionPriority?: number + selector: string + disableForSelector?: string + getSuggestions: (options: RequestOptions) => Promise + onDidInsertSuggestion?: (args: InsertArgs) => any +} + +export interface InsertArgs { + editor: AtomCore.IEditor, + triggerPosition: TextBuffer.IPoint, + suggestion: Suggestion +} diff --git a/lib/typings/bluebird.d.ts b/lib/typings/bluebird.d.ts deleted file mode 100644 index 70afe0a6b..000000000 --- a/lib/typings/bluebird.d.ts +++ /dev/null @@ -1,142 +0,0 @@ -// Type definitions for es6-promises -// Project: https://github.com/jakearchibald/ES6-Promises -// Definitions by: François de Campredon -// Definitions: https://github.com/borisyankov/DefinitelyTyped - -/*tslint:disable unused*/ -declare module 'bluebird' { - class Promise implements Promise.Thenable { - /** - * If you call resolve in the body of the callback passed to the constructor, - * your promise is fulfilled with result object passed to resolve. - * If you call reject your promise is rejected with the object passed to resolve. - * For consistency and debugging (eg stack traces), obj should be an instanceof Error. - * Any errors thrown in the constructor callback will be implicitly passed to reject(). - */ - constructor(callback: (resolve: (result: R) => void, reject: (error: any) => void) => void); - /** - * If you call resolve in the body of the callback passed to the constructor, - * your promise will be fulfilled/rejected with the outcome of thenable passed to resolve. - * If you call reject your promise is rejected with the object passed to resolve. - * For consistency and debugging (eg stack traces), obj should be an instanceof Error. - * Any errors thrown in the constructor callback will be implicitly passed to reject(). - */ - constructor(callback: (resolve: (thenable: Promise.Thenable) => void, reject: (error: any) => void) => void); - - - /** - * onFulFill is called when/if "promise" resolves. onRejected is called when/if "promise" rejects. - * Both are optional, if either/both are omitted the next onFulfilled/onRejected in the chain is called. - * Both callbacks have a single parameter , the fulfillment value or rejection reason. - * "then" returns a new promise equivalent to the value you return from onFulfilled/onRejected after - * being passed through Promise.resolve. - * If an error is thrown in the callback, the returned promise rejects with that error. - * - * @param onFulFill called when/if "promise" resolves - * @param onReject called when/if "promise" rejects - */ - then(onFulfill: (value: R) => Promise.Thenable, onReject: (error: any) => Promise.Thenable): Promise; - /** - * onFulFill is called when/if "promise" resolves. onRejected is called when/if "promise" rejects. - * Both are optional, if either/both are omitted the next onFulfilled/onRejected in the chain is called. - * Both callbacks have a single parameter , the fulfillment value or rejection reason. - * "then" returns a new promise equivalent to the value you return from onFulfilled/onRejected after - * being passed through Promise.resolve. - * If an error is thrown in the callback, the returned promise rejects with that error. - * - * @param onFulFill called when/if "promise" resolves - * @param onReject called when/if "promise" rejects - */ - then(onFulfill: (value: R) => Promise.Thenable, onReject?: (error: any) => U): Promise; - /** - * onFulFill is called when/if "promise" resolves. onRejected is called when/if "promise" rejects. - * Both are optional, if either/both are omitted the next onFulfilled/onRejected in the chain is called. - * Both callbacks have a single parameter , the fulfillment value or rejection reason. - * "then" returns a new promise equivalent to the value you return from onFulfilled/onRejected after - * being passed through Promise.resolve. - * If an error is thrown in the callback, the returned promise rejects with that error. - * - * @param onFulFill called when/if "promise" resolves - * @param onReject called when/if "promise" rejects - */ - then(onFulfill: (value: R) => U, onReject: (error: any) => Promise.Thenable): Promise; - /** - * onFulFill is called when/if "promise" resolves. onRejected is called when/if "promise" rejects. - * Both are optional, if either/both are omitted the next onFulfilled/onRejected in the chain is called. - * Both callbacks have a single parameter , the fulfillment value or rejection reason. - * "then" returns a new promise equivalent to the value you return from onFulfilled/onRejected after - * being passed through Promise.resolve. - * If an error is thrown in the callback, the returned promise rejects with that error. - * - * @param onFulFill called when/if "promise" resolves - * @param onReject called when/if "promise" rejects - */ - then(onFulfill?: (value: R) => U, onReject?: (error: any) => U): Promise; - - - /** - * Sugar for promise.then(undefined, onRejected) - * - * @param onReject called when/if "promise" rejects - */ - catch(onReject?: (error: any) => Promise.Thenable): Promise; - /** - * Sugar for promise.then(undefined, onRejected) - * - * @param onReject called when/if "promise" rejects - */ - catch(onReject?: (error: any) => U): Promise; - } - - module Promise { - - export interface Thenable { - then(onFulfilled: (value: R) => Thenable, onRejected: (error: any) => Thenable): Thenable; - then(onFulfilled: (value: R) => Thenable, onRejected?: (error: any) => U): Thenable; - then(onFulfilled: (value: R) => U, onRejected: (error: any) => Thenable): Thenable; - then(onFulfilled?: (value: R) => U, onRejected?: (error: any) => U): Thenable; - } - - /** - * Returns promise (only if promise.constructor == Promise) - */ - function cast(promise: Promise): Promise; - /** - * Make a promise that fulfills to obj. - */ - function cast(object?: R): Promise; - - - /** - * Make a new promise from the thenable. - * A thenable is promise-like in as far as it has a "then" method. - * This also creates a new promise if you pass it a genuine JavaScript promise, - * making it less efficient for casting than Promise.cast. - */ - function resolve(thenable: Promise.Thenable): Promise; - /** - * Make a promise that fulfills to obj. Same as Promise.cast(obj) in this situation. - */ - function resolve(object?: R): Promise; - - /** - * Make a promise that rejects to obj. For consistency and debugging (eg stack traces), obj should be an instanceof Error - */ - function reject(error?: any): Promise; - - /** - * Make a promise that fulfills when every item in the array fulfills, and rejects if (and when) any item rejects. - * the array passed to all can be a mixture of promise-like objects and other objects. - * The fulfillment value is an array (in order) of fulfillment values. The rejection value is the first rejection value. - */ - function all(promises: Promise[]): Promise; - - /** - * Make a Promise that fulfills when any item fulfills, and rejects if any item rejects. - */ - function race(promises: Promise[]): Promise; - } - - - export = Promise; -} diff --git a/lib/typings/brackets.d.ts b/lib/typings/brackets.d.ts deleted file mode 100644 index 73143b4bb..000000000 --- a/lib/typings/brackets.d.ts +++ /dev/null @@ -1,1172 +0,0 @@ -// Copyright 2013-2014 François de Campredon -// -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. - - -/// - - - -//-------------------------------------------------------------------------- -// -// Brackets declaration files -// -//-------------------------------------------------------------------------- - - - - -declare module brackets { - - - //-------------------------------------------------------------------------- - // - // FileSystem - // - //-------------------------------------------------------------------------- - - /** - * FileSystem is a model object representing a complete file system. This object creates - * and manages File and Directory instances, dispatches events when the file system changes, - * and provides methods for showing 'open' and 'save' dialogs. - * - * The FileSystem must be initialized very early during application startup. - * - * There are three ways to get File or Directory instances: - * * Use FileSystem.resolve() to convert a path to a File/Directory object. This will only - * succeed if the file/directory already exists. - * * Use FileSystem.getFileForPath()/FileSystem.getDirectoryForPath() if you know the - * file/directory already exists, or if you want to create a new entry. - * * Use Directory.getContents() to return all entries for the specified Directory. - * - * FileSystem dispatches the following events: - * change - Sent whenever there is a change in the file system. The handler - * is passed one argument -- entry. This argument can be... - * * a File - the contents of the file have changed, and should be reloaded. - * * a Directory - an immediate child of the directory has been added, removed, - * or renamed/moved. Not triggered for "grandchildren". - * * null - a 'wholesale' change happened, and you should assume everything may - * have changed. - * For changes made externally, there may be a significant delay before a "change" event - * is dispatched. - * rename - Sent whenever a File or Directory is renamed. All affected File and Directory - * objects have been updated to reflect the new path by the time this event is dispatched. - * This event should be used to trigger any UI updates that may need to occur when a path - * has changed. - * - * FileSystem may perform caching. But it guarantees: - * * File contents & metadata - reads are guaranteed to be up to date (cached data is not used - * without first veryifying it is up to date). - * * Directory structure / file listing - reads may return cached data immediately, which may not - * reflect external changes made recently. (However, changes made via FileSystem itself are always - * reflected immediately, as soon as the change operation's callback signals success). - * - * The FileSystem doesn't directly read or write contents--this work is done by a low-level - * implementation object. This allows client code to use the FileSystem API without having to - * worry about the underlying storage, which could be a local filesystem or a remote server. - */ - interface FileSystem { - // should not expose thoses method one - //init(impl, callback) - //close(callback) - //shouldShow - - /** - * Return a File object for the specified path.This file may not yet exist on disk. - * - * @param path Absolute path of file. - */ - getFileForPath(path: string): File; - - /** - * Return a Directory object for the specified path.This directory may not yet exist on disk. - * - * @param path Absolute path of directory. - */ - getDirectoryForPath(path: string): Directory; - - /** - * Resolve a path. - * - * @param path The path to resolve - * @param callback Callback resolved with a FileSystemError string or with the entry for the provided path. - */ - resolve(path: string, callback: (err: string, entry: FileSystemEntry, stat: FileSystemStats) => any): void; - - - /** - * Show an "Open" dialog and return the file(s)/directories selected by the user. - * - * @param allowMultipleSelection Allows selecting more than one file at a time - * @param chooseDirectories Allows directories to be opened - * @param title The title of the dialog - * @param initialPath The folder opened inside the window initially. If initialPath - * is not set, or it doesn't exist, the window would show the last - * browsed folder depending on the OS preferences - * @param fileTypes List of extensions that are allowed to be opened. A null value - * allows any extension to be selected. - * @param callback Callback resolved with a FileSystemError - * string or the selected file(s)/directories. If the user cancels the - * open dialog, the error will be falsy and the file/directory array will - * be empty. - */ - showOpenDialog(allowMultipleSelection: boolean, chooseDirectories: boolean, title: string, initialPath: string, - fileTypes: string[], callback: (err: string, files: string[]) => any): void; - - /** - * Show a "Save" dialog and return the path of the file to save. - * - * @param title The title of the dialog. - * @param initialPath The folder opened inside the window initially. If initialPath - * is not set, or it doesn't exist, the window would show the last - * browsed folder depending on the OS preferences. - * @param proposedNewFilename Provide a new file name for the user. This could be based on - * on the current file name plus an additional suffix - * @param callback Callback that is resolved with a FileSystemError - * string or the name of the file to save. If the user cancels the save, - * the error will be falsy and the name will be empty. - */ - showSaveDialog(title: string, initialPath: string, proposedNewFilename: string, callback: (err: string, file: string) => any): void; - - /** - * Start watching a filesystem root entry. - * - * @param entry The root entry to watch. If entry is a directory, - * all subdirectories that aren't explicitly filtered will also be watched. - * @param filter A function to determine whether - * a particular name should be watched or ignored. Paths that are ignored are also - * filtered from Directory.getContents() results within this subtree. - * @param callback A function that is called when the watch has completed. - * If the watch fails, the function will have a non-null FileSystemError string parametr. - */ - watch(entry: FileSystemEntry, filter: (file: string) => boolean, callback?: (file: string) => void): void; - - /** - * Stop watching a filesystem root entry. - * - * @param {FileSystemEntry} entry - The root entry to stop watching. The unwatch will - * if the entry is not currently being watched. - * @param {function(?string)=} callback - A function that is called when the unwatch has - * completed. If the unwatch fails, the function will have a non-null FileSystemError - * string parameter. - */ - unwatch(entry: FileSystemEntry, callback?: (file: string) => void): void; - - /** - * return true if the path is absolute - * - * @param path - */ - isAbsolutePath(path: string): boolean; - - - /** - * Add an event listener for a FileSystem event. - * - * @param event The name of the event - * @param handler The handler for the event - */ - on(event: string, handler: (...args: any[]) => any): void; - - /** - * Remove an event listener for a FileSystem event. - * - * @param event The name of the event - * @param handler The handler for the event - */ - off(event: string, handler: (...args: any[]) => any): void; - } - - - /** - * This is an abstract representation of a FileSystem entry, and the base class for the File and Directory classes. - * FileSystemEntry objects are never created directly by client code. Use FileSystem.getFileForPath(), - * FileSystem.getDirectoryForPath(), or Directory.getContents() to create the entry. - */ - interface FileSystemEntry { - fullPath: string; - name: string; - parentPath: string; - id: string; - isFile: boolean; - isDirectory: boolean; - - /** - * Check to see if the entry exists on disk. Note that there will NOT be an - * error returned if the file does not exist on the disk; in that case the - * error parameter will be null and the boolean will be false. The error - * parameter will only be truthy when an unexpected error was encountered - * during the test, in which case the state of the entry should be considered - * unknown. - * - * @param callback Callback with a FileSystemError - * string or a boolean indicating whether or not the file exists. - */ - exists(callback: (err: string, exist: boolean) => any): void; - - - /** - * Returns the stats for the entry. - * - * @param callback Callback with a FileSystemError string or FileSystemStats object. - */ - stat(callback: (err: string, stat: FileSystemStats) => any): void; - - /** - * Rename this entry. - * - * @param {string} newFullPath New path & name for this entry. - * @param {function (?string)=} callback Callback with a single FileSystemError string parameter. - */ - rename(newFullPath: string, callback?: (err: string) => any): void; - - - /** - * Unlink (delete) this entry. For Directories, this will delete the directory - * and all of its contents. - * - * @param callback Callback with a single FileSystemError string parameter. - */ - unlink(callback?: (err: string) => any): void; - - - /** - * Move this entry to the trash. If the underlying file system doesn't support move - * to trash, the item is permanently deleted. - * - * @param callback Callback with a single FileSystemError string parameter. - */ - - moveToTrash(callback?: (err: string) => any): void; - - /** - * Visit this entry and its descendents with the supplied visitor function. - * - * @paramvisitor - A visitor function, which is applied to descendent FileSystemEntry objects. If the function returns false for - * a particular Directory entry, that directory's descendents will not be visited. - * @param {{failFast: boolean=, maxDepth: number=, maxEntries: number=}=} options - * @param {function(?string)=} callback Callback with single FileSystemError string parameter. - */ - visit(visitor: (entry: FileSystemEntry) => boolean, options: {failFast?: boolean; maxDepth?: number; maxEntries?: number}, - callbak: (err: string) => any): void; - } - - /** - * This class represents a directory on disk (this could be a local disk or cloud storage). This is a subclass of FileSystemEntry. - */ - interface Directory extends FileSystemEntry { - /** - * Read the contents of a Directory. - * - * @param callback Callback that is passed an error code or the stat-able contents - * of the directory along with the stats for these entries and a - * fullPath-to-FileSystemError string map of unstat-able entries - * and their stat errors. If there are no stat errors then the last - * parameter shall remain undefined. - */ - getContents(callback: (err: string, files: FileSystemEntry[], - stats: FileSystemStats, errors: { [path: string]: string; }) => any): void; - - - /** - * Create a directory - * - * @param callback Callback resolved with a FileSystemError string or the stat object for the created directory. - */ - create(callback: (err: string, stat: FileSystemStats) => any): void; - } - - /** - * This class represents a file on disk (this could be a local disk or cloud storage). This is a subclass of FileSystemEntry. - */ - interface File extends FileSystemEntry { - /** - * Read a file. - * - * @param options Currently unused. - * @param callback Callback that is passed the FileSystemError string or the file's contents and its stats. - */ - read(options: {}, callback: (err: string, data: string, stat: FileSystemStats) => any): void; - - - /** - * Write a file. - * - * @param data Data to write. - * @param options Currently unused. - * @param callback Callback that is passed the FileSystemError string or the file's new stats. - */ - write(data: string, options?: {}, callback?: (err: string, stat: FileSystemStats) => any ): void; - - - - } - - interface FileSystemStats { - isFile: boolean; - isDirectory: boolean; - mtime: Date; - size: number; - } - - //-------------------------------------------------------------------------- - // - // Project - // - //-------------------------------------------------------------------------- - - - - - /** - * ProjectManager is the model for the set of currently open project. It is responsible for - * creating and updating the project tree when projects are opened and when changes occur to - * the file tree. - * - * This module dispatches these events: - * - beforeProjectClose -- before _projectRoot changes - * - beforeAppClose -- before Brackets quits entirely - * - projectOpen -- after _projectRoot changes and the tree is re-rendered - * - projectRefresh -- when project tree is re-rendered for a reason other than - * a project being opened (e.g. from the Refresh command) - * - * These are jQuery events, so to listen for them you do something like this: - * $(ProjectManager).on("eventname", handler); - */ - interface ProjectManager { - /** - * Returns the root folder of the currently loaded project, or null if no project is open (during - * startup, or running outside of app shell). - */ - getProjectRoot(): Directory; - - /** - * Returns the encoded Base URL of the currently loaded project, or empty string if no project - * is open (during startup, or running outside of app shell). - */ - getBaseUrl(): string; - - /** - * Sets the encoded Base URL of the currently loaded project. - * @param {String} - */ - setBaseUrl(): string; - - /** - * Returns true if absPath lies within the project, false otherwise. - * Does not support paths containing ".." - */ - isWithinProject(absPath: string): boolean; - - /** - * If absPath lies within the project, returns a project-relative path. Else returns absPath - * unmodified. - * Does not support paths containing ".." - * @param absPath - */ - makeProjectRelativeIfPossible(absPath: string): string; - - /** - * Returns false for files and directories that are not commonly useful to display. - * - * @param entry File or directory to filter - */ - shouldShow(entry: FileSystemEntry): boolean; - - /** - * Returns true if fileName's extension doesn't belong to binary (e.g. archived) - * @param fileName - */ - isBinaryFile(fileName: string): boolean; - - /** - * Open a new project. Currently, Brackets must always have a project open, so - * this method handles both closing the current project and opening a new project. - * return {$.Promise} A promise object that will be resolved when the - * project is loaded and tree is rendered, or rejected if the project path - * fails to load. - * - * @param path Optional absolute path to the root folder of the project. - * If path is undefined or null, displays a dialog where the user can choose a - * folder to load. If the user cancels the dialog, nothing more happens. - - */ - openProject(path?: string): JQueryPromise; - - /** - * Returns the File or Directory corresponding to the item selected in the sidebar panel, whether in - * the file tree OR in the working set; or null if no item is selected anywhere in the sidebar. - * May NOT be identical to the current Document - a folder may be selected in the sidebar, or the sidebar may not - * have the current document visible in the tree & working set. - */ - getSelectedItem(): FileSystemEntry; - - /** - * Returns an Array of all files for this project, optionally including - * files in the working set that are *not* under the project root. Files filtered - * out by shouldShow() OR isBinaryFile() are excluded. - * - * @param filter Optional function to filter - * the file list (does not filter directory traversal). API matches Array.filter(). - * @param includeWorkingSet If true, include files in the working set - * that are not under the project root (*except* for untitled documents). - * - * @return {$.Promise} Promise that is resolved with an Array of File objects. - */ - getAllFiles(filter?: (file: File) => boolean, includeWorkingSet?: boolean): JQueryPromise; - - /* - TODO - getInitialProjectPath; - isWelcomeProjectPath; - updateWelcomeProjectPath; - createNewItem; - renameItemInline; - deleteItem; - forceFinishRename; - showInTree; - refreshFileTree; - - getLanguageFilter; - - */ - } - - //-------------------------------------------------------------------------- - // - // Document - // - //-------------------------------------------------------------------------- - - /** - * DocumentManager maintains a list of currently 'open' Documents. It also owns the list of files in - * the working set, and the notion of which Document is currently shown in the main editor UI area. - * - * Document is the model for a file's contents; it dispatches events whenever those contents change. - * To transiently inspect a file's content, simply get a Document and call getText() on it. However, - * to be notified of Document changes or to modify a Document, you MUST call addRef() to ensure the - * Document instance 'stays alive' and is shared by all other who read/modify that file. ('Open' - * Documents are all Documents that are 'kept alive', i.e. have ref count > 0). - * - * To get a Document, call getDocumentForPath(); never new up a Document yourself. - * - * Secretly, a Document may use an Editor instance to act as the model for its internal state. (This - * is unavoidable because CodeMirror does not separate its model from its UI). Documents are not - * modifiable until they have a backing 'master Editor'. Creation of the backing Editor is owned by - * EditorManager. A Document only gets a backing Editor if it becomes the currentDocument, or if edits - * occur in any Editor (inline or full-sized) bound to the Document; there is currently no other way - * to ensure a Document is modifiable. - * - * A non-modifiable Document may still dispatch change notifications, if the Document was changed - * externally on disk. - * - * Aside from the text content, Document tracks a few pieces of metadata - notably, whether there are - * any unsaved changes. - * - * This module dispatches several events: - * - * - dirtyFlagChange -- When any Document's isDirty flag changes. The 2nd arg to the listener is the - * Document whose flag changed. - * - documentSaved -- When a Document's changes have been saved. The 2nd arg to the listener is the - * Document that has been saved. - * - documentRefreshed -- When a Document's contents have been reloaded from disk. The 2nd arg to the - * listener is the Document that has been refreshed. - * - * - currentDocumentChange -- When the value of getCurrentDocument() changes. - * - * To listen for working set changes, you must listen to *all* of these events: - * - workingSetAdd -- When a file is added to the working set (see getWorkingSet()). The 2nd arg - * to the listener is the added File, and the 3rd arg is the index it was inserted at. - * - workingSetAddList -- When multiple files are added to the working set (e.g. project open, multiple file open). - * The 2nd arg to the listener is the array of added File objects. - * - workingSetRemove -- When a file is removed from the working set (see getWorkingSet()). The - * 2nd arg to the listener is the removed File. - * - workingSetRemoveList -- When multiple files are removed from the working set (e.g. project close). - * The 2nd arg to the listener is the array of removed File objects. - * - workingSetSort -- When the workingSet array is reordered without additions or removals. - * Listener receives no arguments. - * - * - workingSetDisableAutoSorting -- Dispatched in addition to workingSetSort when the reorder was caused - * by manual dragging and dropping. Listener receives no arguments. - * - * - fileNameChange -- When the name of a file or folder has changed. The 2nd arg is the old name. - * The 3rd arg is the new name. - * - pathDeleted -- When a file or folder has been deleted. The 2nd arg is the path that was deleted. - * - * These are jQuery events, so to listen for them you do something like this: - * $(DocumentManager).on("eventname", handler); - * - * Document objects themselves also dispatch some events - see Document docs for details. - */ - export interface DocumentManager { - /** - * Returns the Document that is currently open in the editor UI. May be null. - * When this changes, DocumentManager dispatches a "currentDocumentChange" event. The current - * document always has a backing Editor (Document._masterEditor != null) and is thus modifiable. - */ - getCurrentDocument(): Document; - - /** Changes currentDocument to null, causing no full Editor to be shown in the UI */ - _clearCurrentDocument(): void; - - /** - * Gets an existing open Document for the given file, or creates a new one if the Document is - * not currently open ('open' means referenced by the UI somewhere). Always use this method to - * get Documents; do not call the Document constructor directly. This method is safe to call - * in parallel. - * - * If you are going to hang onto the Document for more than just the duration of a command - e.g. - * if you are going to display its contents in a piece of UI - then you must addRef() the Document - * and listen for changes on it. (Note: opening the Document in an Editor automatically manages - * refs and listeners for that Editor UI). - * - * @param fullPath - * @return {$.Promise} A promise object that will be resolved with the Document, or rejected - * with a FileSystemError if the file is not yet open and can't be read from disk. - */ - getDocumentForPath(fullPath: string): JQueryPromise; - - /** - * Returns the existing open Document for the given file, or null if the file is not open ('open' - * means referenced by the UI somewhere). If you will hang onto the Document, you must addRef() - * it; see {@link getDocumentForPath()} for details. - * @param fullPath - */ - getOpenDocumentForPath(fullPath: string): Document; - - /** - * Gets the text of a Document (including any unsaved changes), or would-be Document if the - * file is not actually open. More efficient than getDocumentForPath(). Use when you're reading - * document(s) but don't need to hang onto a Document object. - * - * If the file is open this is equivalent to calling getOpenDocumentForPath().getText(). If the - * file is NOT open, this is like calling getDocumentForPath()...getText() but more efficient. - * Differs from plain FileUtils.readAsText() in two ways: (a) line endings are still normalized - * as in Document.getText(); (b) unsaved changes are returned if there are any. - * - * @param file - */ - getDocumentText(file: File): JQueryPromise; - - /** - * Creates an untitled document. The associated File has a fullPath that - * looks like /some-random-string/Untitled-counter.fileExt. - * - * @param counter - used in the name of the new Document's File - * @param fileExt - file extension of the new Document's File - * @return {Document} - a new untitled Document - */ - createUntitledDocument(counter: number, fileExt: string): Document; - - - /** - * Returns a list of items in the working set in UI list order. May be 0-length, but never null. - * - * When a file is added this list, DocumentManager dispatches a "workingSetAdd" event. - * When a file is removed from list, DocumentManager dispatches a "workingSetRemove" event. - * To listen for ALL changes to this list, you must listen for both events. - * - * Which items belong in the working set is managed entirely by DocumentManager. Callers cannot - * (yet) change this collection on their own. - * - */ - getWorkingSet(): File[]; - - /** - * Returns the index of the file matching fullPath in the working set. - * Returns -1 if not found. - * @param fullPath - * @param list Pass this arg to search a different array of files. Internal - * use only. - * @returns {number} index - */ - findInWorkingSet(fullPath: string, list?: File[]): number; - /*TODO - findInWorkingSetAddedOrder() - getAllOpenDocuments() - setCurrentDocument() - addToWorkingSet() - addListToWorkingSet() - removeFromWorkingSet() - removeListFromWorkingSet() - getNextPrevFile() - swapWorkingSetIndexes() - sortWorkingSet() - beginDocumentNavigation() - finalizeDocumentNavigation() - closeFullEditor() - closeAll() - notifyFileDeleted() - notifyPathNameChanged() - notifyPathDeleted()*/ - } - - - /** - * Model for the contents of a single file and its current modification state. - * See DocumentManager documentation for important usage notes. - * - * Document dispatches these events: - * - * change -- When the text of the editor changes (including due to undo/redo). - * - * Passes ({Document}, {ChangeList}), where ChangeList is a linked list (NOT an array) - * of change record objects. Each change record looks like: - * - * { from: start of change, expressed as {line: , ch: }, - * to: end of change, expressed as {line: , ch: }, - * text: array of lines of text to replace existing text, - * next: next change record in the linked list, or undefined if this is the last record } - * - * The line and ch offsets are both 0-based. - * - * The ch offset in "from" is inclusive, but the ch offset in "to" is exclusive. For example, - * an insertion of new content (without replacing existing content) is expressed by a range - * where from and to are the same. - * - * If "from" and "to" are undefined, then this is a replacement of the entire text content. - * - * IMPORTANT: If you listen for the "change" event, you MUST also addRef() the document - * (and releaseRef() it whenever you stop listening). You should also listen to the "deleted" - * event. - * - * (FUTURE: this is a modified version of the raw CodeMirror change event format; may want to make - * it an ordinary array) - * - * deleted -- When the file for this document has been deleted. All views onto the document should - * be closed. The document will no longer be editable or dispatch "change" events. - * - */ - interface Document { - /** - * The File for this document. Need not lie within the project. - * If Document is untitled, this is an InMemoryFile object. - */ - file: File; - - /** - * The Language for this document. Will be resolved by file extension in the constructor - * @type {!Language} - */ - //TODO language: Language; - - /** - * Whether this document has unsaved changes or not. - * When this changes on any Document, DocumentManager dispatches a "dirtyFlagChange" event. - */ - isDirty: boolean; - - /** - * Returns the document's current contents; may not be saved to disk yet. Whenever this - * value changes, the Document dispatches a "change" event. - * - * @param useOriginalLineEndings If true, line endings in the result depend on the - * Document's line endings setting (based on OS & the original text loaded from disk). - * If false, line endings are always \n (like all the other Document text getter methods). - */ - getText(useOriginalLineEndings?: boolean): string; - - /** - * Adds, replaces, or removes text. If a range is given, the text at that range is replaced with the - * given new text; if text == "", then the entire range is effectively deleted. If 'end' is omitted, - * then the new text is inserted at that point and all existing text is preserved. Line endings will - * be rewritten to match the document's current line-ending style. - * - * IMPORTANT NOTE: Because of #1688, do not use this in cases where you might be - * operating on a linked document (like the main document for an inline editor) - * during an outer CodeMirror operation (like a key event that's handled by the - * editor itself). A common case of this is code hints in inline editors. In - * such cases, use `editor._codeMirror.replaceRange()` instead. This should be - * fixed when we migrate to use CodeMirror's native document-linking functionality. - * - * @param text Text to insert or replace the range with - * @param start Start of range, inclusive (if 'to' specified) or insertion point (if not) - * @param end End of range, exclusive; optional - * @param origin Optional string used to batch consecutive edits for undo. - * If origin starts with "+", then consecutive edits with the same origin will be batched for undo if - * they are close enough together in time. - * If origin starts with "*", then all consecutive edit with the same origin will be batched for - * undo. - * Edits with origins starting with other characters will not be batched. - * (Note that this is a higher level of batching than batchOperation(), which already batches all - * edits within it for undo. Origin batching works across operations.) - */ - replaceRange(text: string, start: CodeMirror.Position, end?: CodeMirror.Position, origin?: string): void; - - /** - * Returns the text of the given line (excluding any line ending characters) - * @param index Zero-based line number - */ - getLine(index: number): string; - - /** - * Sets the contents of the document. Treated as an edit. Line endings will be rewritten to - * match the document's current line-ending style. - * @param text The text to replace the contents of the document with. - */ - setText(text: string): void; - - //TODO imcomplete - } - - //-------------------------------------------------------------------------- - // - // Editor - // - //-------------------------------------------------------------------------- - - /** - * Editor is a 1-to-1 wrapper for a CodeMirror editor instance. It layers on Brackets-specific - * functionality and provides APIs that cleanly pass through the bits of CodeMirror that the rest - * of our codebase may want to interact with. An Editor is always backed by a Document, and stays - * in sync with its content; because Editor keeps the Document alive, it's important to always - * destroy() an Editor that's going away so it can release its Document ref. - * - * For now, there's a distinction between the "master" Editor for a Document - which secretly acts - * as the Document's internal model of the text state - and the multitude of "slave" secondary Editors - * which, via Document, sync their changes to and from that master. - * - * For now, direct access to the underlying CodeMirror object is still possible via _codeMirror -- - * but this is considered deprecated and may go away. - * - * The Editor object dispatches the following events: - * - keyEvent -- When any key event happens in the editor (whether it changes the text or not). - * Event handlers are passed ({Editor}, {KeyboardEvent}). The 2nd arg is the raw DOM event. - * Note: most listeners will only want to respond when event.type === "keypress". - * - cursorActivity -- When the user moves the cursor or changes the selection, or an edit occurs. - * Note: do not listen to this in order to be generally informed of edits--listen to the - * "change" event on Document instead. - * - scroll -- When the editor is scrolled, either by user action or programmatically. - * - lostContent -- When the backing Document changes in such a way that this Editor is no longer - * able to display accurate text. This occurs if the Document's file is deleted, or in certain - * Document->editor syncing edge cases that we do not yet support (the latter cause will - * eventually go away). - * - optionChange -- Triggered when an option for the editor is changed. The 2nd arg to the listener - * is a string containing the editor option that is changing. The 3rd arg, which can be any - * data type, is the new value for the editor option. - * - * The Editor also dispatches "change" events internally, but you should listen for those on - * Documents, not Editors. - * - * These are jQuery events, so to listen for them you do something like this: - * $(editorInstance).on("eventname", handler); - */ - interface Editor { - _codeMirror: CodeMirror.Editor; - document: Document; - getCursorPos(): CodeMirror.Position; - getModeForSelection(): string; - getSelection(boolean: boolean): { - start: CodeMirror.Position; - end: CodeMirror.Position - }; - setCursorPos(line: number, ch: number, center: boolean, expandTabs: boolean): void ; - } - - - interface EditorManager { - registerInlineEditProvider(provider: InlineEditProvider, priority?: number): void; - registerInlineDocsProvider(provider: InlineDocsProvider, priority?: number): void; - registerJumpToDefProvider(provider: JumpDoDefProvider): void; - getFocusedEditor(): Editor; - /** - * Returns the current active editor (full-sized OR inline editor). This editor may not - * have focus at the moment, but it is visible and was the last editor that was given - * focus. Returns null if no editors are active. - * @see getFocusedEditor() - * @returns {?Editor} - */ - getActiveEditor(): Editor; - getCurrentFullEditor(): Editor; - } - - //-------------------------------------------------------------------------- - // - // Editor - // - //-------------------------------------------------------------------------- - - /** - * PreferencesManager - * - */ - interface PreferencesManager extends Preferences { - /** - * Creates an extension-specific preferences manager using the prefix given. - * A `.` character will be appended to the prefix. So, a preference named `foo` - * with a prefix of `myExtension` will be stored as `myExtension.foo` in the - * preferences files. - * - * @param prefix Prefix to be applied - */ - getExtensionPrefs(prefix: string): Preferences; - - - /** - * Get the full path to the user-level preferences file. - * - * @return Path to the preferences file - */ - getUserPrefFile(): string; - - /** - * Context to look up preferences for the currently edited file. - * This is undefined because this is the default behavior of PreferencesSystem.get. - */ - CURRENT_FILE: any; - /** - * Context to look up preferences in the current project. - */ - CURRENT_PROJECT: any; - } - - interface Preferences { - /** - * Defines a new (prefixed) preference. - * - * @param id unprefixed identifier of the preference. Generally a dotted name. - * @param type Data type for the preference (generally, string, boolean, number) - * @param initial Default value for the preference - * @param options Additional options for the pref. Can include name and description - * that will ultimately be used in UI. - * @return {Object} The preference object. - */ - definePreference(id: string, type: string, value: any, options?: { name?: string; description: string; }): any; - - - /** - * Get the prefixed preference object - * - * @param {string} id ID of the pref to retrieve. - */ - getPreference(id: string): any; - - /** - * Gets the prefixed preference - * - * @param id Name of the preference for which the value should be retrieved - * @param context Optional context object to change the preference lookup - */ - get(id: string, context?: any): any; - - /** - * Gets the location in which the value of a prefixed preference has been set. - * - * @param id Name of the preference for which the value should be retrieved - * @param context Optional context object to change the preference lookup - * @return Object describing where the preferences came from - */ - getPreferenceLocation(id: string, context?: any): {scope: string; layer?: string; layerID?: any}; - - /** - * Sets the prefixed preference - * - * @param id Identifier of the preference to set - * @param value New value for the preference - * @param options Specific location in which to set the value or the context to use when setting the value - * @return true if a value was set - */ - set(id: string, value: any, options?: {location: any; context?: any; }): boolean; - - - /** - * Sets up a listener for events for this PrefixedPreferencesSystem. Only prefixed events - * will notify. Optionally, you can set up a listener for a - * specific preference. - * - * @param event Name of the event to listen for - * @param preferenceID Name of a specific preference - * @param handler Handler for the event - */ - on(event: string, preferenceId: string, handler: (...rest: any[]) => void): void; - /** - * Sets up a listener for events for this PrefixedPreferencesSystem. Only prefixed events - * will notify. Optionally, you can set up a listener for a - * specific preference. - * - * @param event Name of the event to listen for - * @param handler Handler for the event - */ - on(event: string, handler: (...rest: any[]) => void): void; - - - /** - * Turns off the event handlers for a given event, optionally for a specific preference - * or a specific handler function. - * - * @param event Name of the event for which to turn off listening - * @param preferenceID Name of a specific preference - * @param handler Specific handler which should stop being notified - */ - off(event: string, preferenceId: string, handler: (...rest: any[]) => void): void; - /** - * Turns off the event handlers for a given event, optionally for a specific preference - * or a specific handler function. - * - * @param event Name of the event to listen for - * @param handler Specific handler which should stop being notified - */ - off(event: string, handler: (...rest: any[]) => void): void; - - - /** - * Saves the preferences. If a save is already in progress, a Promise is returned for - * that save operation. - * - * @return a promise resolved when the preferences are done saving. - */ - save(): JQueryPromise; - } - - - - //-------------------------------------------------------------------------- - // - // PanelManager - // - //-------------------------------------------------------------------------- - - /** - * Represents a panel below the editor area (a child of ".content"). - */ - interface Panel { - isVisible(): boolean; - show(): void; - hide(): void; - setVisible(visible: boolean): void; - $panel: JQuery - } - - /** - * Manages layout of panels surrounding the editor area, and size of the editor area (but not its contents). - * - * Updates panel sizes when the window is resized. Maintains the max resizing limits for panels, based on - * currently available window size. - * - * Events: - * - editorAreaResize -- When editor-holder's size changes for any reason (including panel show/hide - * panel resize, or the window resize). - * The 2nd arg is the new editor-holder height. - * The 3rd arg is a refreshHint flag for internal EditorManager use. - */ - - interface PanelManager { - /** - * Creates a new panel beneath the editor area and above the status bar footer. Panel is initially invisible. - * - * @param id Unique id for this panel. Use package-style naming, e.g. "myextension.feature.panelname" - * @param $panel DOM content to use as the panel. Need not be in the document yet. - * @param minSize Minimum height of panel in px. - */ - createBottomPanel(id: string, $panel: JQuery, minSize: number): Panel; - } - - //-------------------------------------------------------------------------- - // - // Command - // - //-------------------------------------------------------------------------- - interface CommandManager { - execute(id: string, args: any): JQueryPromise; - register(name: string, id: string, callback: () => void): void; - } - - - //-------------------------------------------------------------------------- - // - // CodeHint - // - //-------------------------------------------------------------------------- - - - interface CodeHintManager { - registerHintProvider(hintProvider: CodeHintProvider, languageIds: string[], priority?: number): void; - } - interface HintResult { - hints?: any []; - match?: string; - selectInitial?: boolean - } - - interface CodeHintProvider { - hasHints(editor: Editor, implicitChar: string): boolean; - getHints(implicitChar: string): JQueryDeferred; - insertHint(hint: any): void; - } - - - //-------------------------------------------------------------------------- - // - // Inspection - // - //-------------------------------------------------------------------------- - - - - interface CodeInspection { - register(languageId: string, provider: InspectionProvider): void; - Type: { [index: string]: string} - } - - - interface LintingError { - pos: CodeMirror.Position; - endPos?: CodeMirror.Position; - message: string; - type?: string; - } - - interface InspectionProvider { - name: string; - scanFile?(content: string, path: string): { errors: LintingError[]; aborted: boolean }; - scanFileAsync?(content: string, path: string): JQueryPromise<{ errors: LintingError[]; aborted: boolean }>; - } - - - //-------------------------------------------------------------------------- - // - // QuickEdit - // - //-------------------------------------------------------------------------- - - interface InlineEditProvider { - (hostEditor: Editor, pos: CodeMirror.Position): JQueryPromise - } - - - - //-------------------------------------------------------------------------- - // - // QuickOpen - // - //-------------------------------------------------------------------------- - - interface QuickOpen { - /** - * Creates and registers a new QuickOpenPlugin - */ - addQuickOpenPlugin(def: QuickOpenPluginDef): void; - highlightMatch(item: string): string; - } - - - interface QuickOpenPluginDef { - /** - * plug-in name, **must be unique** - */ - name: string; - /** - * language Ids array. Example: ["javascript", "css", "html"]. To allow any language, pass []. Required. - */ - languageIds: string[]; - /** - * called when quick open is complete. Plug-in should clear its internal state. Optional. - */ - done?: () => void; - /** - * takes a query string and a StringMatcher (the use of which is optional but can speed up your searches) - * and returns an array of strings that match the query. Required. - */ - search: (request: string, stringMatcher: StringMatcher) => JQueryPromise; - /** - * takes a query string and returns true if this plug-in wants to provide - */ - match: (query: string) => boolean; - /** - * performs an action when a result has been highlighted (via arrow keys, mouseover, etc.). - */ - itemFocus?: (result: S) => void; - /** - * performs an action when a result is chosen. - */ - itemSelect: (result: S) => void; - /** - * takes a query string and an item string and returns - * a
  • item to insert into the displayed search results. Optional. - */ - resultsFormatter?: (result: S) => string; - - /** - * options to pass along to the StringMatcher (see StringMatch.StringMatcher for available options). - */ - matcherOptions?: StringMatcherOptions; - /** - * if provided, the label to show before the query field. Optional. - */ - label?: string; - } - - interface StringMatcherOptions { - preferPrefixMatches?: boolean; - segmentedSearch?: boolean; - } - - interface StringMatcher { - match(target: string, query: string): { - ranges: { text: string; matched: boolean; includesLastSegment: boolean}[]; - matchGoodness: number; - scoreDebug: any; - } - } - - - //-------------------------------------------------------------------------- - // - // Todo - // - //-------------------------------------------------------------------------- - - interface InlineDocsProvider { - (hostEditor: Editor, pos: CodeMirror.Position): JQueryPromise - } - - interface JumpDoDefProvider { - (): JQueryPromise - } - - - - interface InlineWidget { - load(editor: Editor): void - } - - - - module MultiRangeInlineEditor { - class MultiRangeInlineEditor implements InlineWidget { - constructor(ranges: MultiRangeInlineEditorRange[]); - load(editor: Editor): void; - } - } - - interface MultiRangeInlineEditorRange { - name: string; - document: brackets.Document; - lineStart: number; - lineEnd: number; - } - - function getModule(module: 'filesystem/FileSystem'): FileSystem; - function getModule(module: 'document/DocumentManager'): brackets.DocumentManager; - function getModule(module: 'project/ProjectManager'): brackets.ProjectManager; - function getModule(module: 'editor/CodeHintManager'): CodeHintManager; - function getModule(module: 'editor/EditorManager'): EditorManager; - function getModule(module: 'editor/MultiRangeInlineEditor'): typeof MultiRangeInlineEditor; - function getModule(module: 'language/CodeInspection'): CodeInspection; - function getModule(module: 'view/PanelManager'): PanelManager; - function getModule(module: 'command/CommandManager'): CommandManager; - function getModule(module: 'search/QuickOpen'): QuickOpen; - function getModule(module: 'preferences/PreferencesManager'): PreferencesManager; - function getModule(module: string): any; - -} diff --git a/lib/typings/codemirror.d.ts b/lib/typings/codemirror.d.ts deleted file mode 100644 index d63f291af..000000000 --- a/lib/typings/codemirror.d.ts +++ /dev/null @@ -1,849 +0,0 @@ -/*tslint:disable unused*/ - -declare function CodeMirror(host: HTMLElement, options?: CodeMirror.EditorConfiguration): CodeMirror.Editor; -declare function CodeMirror(callback: (host: HTMLElement) => void , options?: CodeMirror.EditorConfiguration): CodeMirror.Editor; - -declare module CodeMirror { - - interface CodeMirrorStream { - eol(): boolean; - sol(): boolean; - peek(): string; - next(): string; - eat(match: string): string; - eat(match: RegExp): string; - eat(match: (char: string) => boolean): string; - eatWhile(match: string): string; - eatWhile(match: RegExp): string; - eatWhile(match: (char: string) => boolean): string; - eatSpace(): boolean; - skipToEnd(): void; - skipTo(ch: string): boolean; - match(pattern: string, consume?: boolean, caseFold?: boolean): boolean; - match(pattern: RegExp, consume?: boolean): string[]; - backUp(n: number): void; - column(): number; - indentation(): number; - current(): string; - - pos: number; - string: string; - } - - interface CodeMirrorMode { - token(stream: CodeMirrorStream, state: T): void; - - startState?: () => T; - blankLine?: (state: T) => void; - copyState?: (state: T) => T; - - indent?: (state: T, textAfter: string) => number; - - lineComment?: string; - blockCommentStart?: string; - blockCommentEnd?: string; - blockCommentLead?: string; - - electricChars?: string - - } - - - interface CodeMirrorModeOptions { - - } - - interface CodeMirrorModeFactory { - (options: CodeMirror.EditorConfiguration, spec: any): CodeMirrorMode - } - - function defineMode(id: string, modefactory: CodeMirrorModeFactory): void; - function defineMIME(mime: string, modeId: string): void; - - var Pass: any; - - function fromTextArea(host: HTMLTextAreaElement, options?: EditorConfiguration): CodeMirror.Editor; - - var version: string; - - /** If you want to define extra methods in terms of the CodeMirror API, it is possible to use defineExtension. - This will cause the given value(usually a method) to be added to all CodeMirror instances created from then on. */ - function defineExtension(name: string, value: any): void; - - /** Like defineExtension, but the method will be added to the interface for Doc objects instead. */ - function defineDocExtension(name: string, value: any): void; - - /** Similarly, defineOption can be used to define new options for CodeMirror. - The updateFunc will be called with the editor instance and the new value when an editor is initialized, - and whenever the option is modified through setOption. */ - function defineOption(name: string, default_: any, updateFunc: Function): void; - - /** If your extention just needs to run some code whenever a CodeMirror instance is initialized, use CodeMirror.defineInitHook. - Give it a function as its only argument, and from then on, that function will be called (with the instance as argument) - whenever a new CodeMirror instance is initialized. */ - function defineInitHook(func: Function): void; - - - - function on(element: any, eventName: string, handler: Function): void; - function off(element: any, eventName: string, handler: Function): void; - - /** Fired whenever a change occurs to the document. changeObj has a similar type as the object passed to the editor's "change" event, - but it never has a next property, because document change events are not batched (whereas editor change events are). */ - function on(doc: Doc, eventName: 'change', handler: (instance: Doc, change: EditorChange) => void ): void; - function off(doc: Doc, eventName: 'change', handler: (instance: Doc, change: EditorChange) => void ): void; - - /** See the description of the same event on editor instances. */ - function on(doc: Doc, eventName: 'beforeChange', handler: (instance: Doc, change: EditorChangeCancellable) => void ): void; - function off(doc: Doc, eventName: 'beforeChange', handler: (instance: Doc, change: EditorChangeCancellable) => void ): void; - - /** Fired whenever the cursor or selection in this document changes. */ - function on(doc: Doc, eventName: 'cursorActivity', handler: (instance: CodeMirror.Editor) => void ): void; - function off(doc: Doc, eventName: 'cursorActivity', handler: (instance: CodeMirror.Editor) => void ): void; - - /** Equivalent to the event by the same name as fired on editor instances. */ - function on(doc: Doc, eventName: 'beforeSelectionChange', - handler: (instance: CodeMirror.Editor, selection: { head: Position; anchor: Position; }) => void ): void; - function off(doc: Doc, eventName: 'beforeSelectionChange', - handler: (instance: CodeMirror.Editor, selection: { head: Position; anchor: Position; }) => void ): void; - - /** Will be fired when the line object is deleted. A line object is associated with the start of the line. - Mostly useful when you need to find out when your gutter markers on a given line are removed. */ - function on(line: LineHandle, eventName: 'delete', handler: () => void ): void; - function off(line: LineHandle, eventName: 'delete', handler: () => void ): void; - - /** Fires when the line's text content is changed in any way (but the line is not deleted outright). - The change object is similar to the one passed to change event on the editor object. */ - function on(line: LineHandle, eventName: 'change', handler: (line: LineHandle, change: EditorChange) => void ): void; - function off(line: LineHandle, eventName: 'change', handler: (line: LineHandle, change: EditorChange) => void ): void; - - /** Fired when the cursor enters the marked range. From this event handler, the editor state may be inspected but not modified, - with the exception that the range on which the event fires may be cleared. */ - function on(marker: TextMarker, eventName: 'beforeCursorEnter', handler: () => void ): void; - function off(marker: TextMarker, eventName: 'beforeCursorEnter', handler: () => void ): void; - - /** Fired when the range is cleared, either through cursor movement in combination with clearOnEnter or - * through a call to its clear() method. - * Will only be fired once per handle. Note that deleting the range through text editing does not fire this event, - * because an undo action might bring the range back into existence. - */ - function on(marker: TextMarker, eventName: 'clear', handler: () => void ): void; - function off(marker: TextMarker, eventName: 'clear', handler: () => void ): void; - - /** Fired when the last part of the marker is removed from the document by editing operations. */ - function on(marker: TextMarker, eventName: 'hide', handler: () => void ): void; - function off(marker: TextMarker, eventName: 'hide', handler: () => void ): void; - - /** Fired when, after the marker was removed by editing, a undo operation brought the marker back. */ - function on(marker: TextMarker, eventName: 'unhide', handler: () => void ): void; - function off(marker: TextMarker, eventName: 'unhide', handler: () => void ): void; - - /** Fired whenever the editor re-adds the widget to the DOM. This will happen once right after the widget is added (if it is scrolled into view), - and then again whenever it is scrolled out of view and back in again, or when changes to the editor options - or the line the widget is on require the widget to be redrawn. */ - function on(line: LineWidget, eventName: 'redraw', handler: () => void ): void; - function off(line: LineWidget, eventName: 'redraw', handler: () => void ): void; - - interface Editor { - - /** Tells you whether the editor currently has focus. */ - hasFocus(): boolean; - - /** Used to find the target position for horizontal cursor motion.start is a { line , ch } object, - amount an integer(may be negative), and unit one of the string "char", "column", or "word". - Will return a position that is produced by moving amount times the distance specified by unit. - When visually is true , motion in right - to - left text will be visual rather than logical. - When the motion was clipped by hitting the end or start of the document, the returned value will have a hitSide property set to true. */ - findPosH(start: CodeMirror.Position, amount: number, unit: string, visually: boolean): { line: number; ch: number; hitSide?: boolean; }; - - /** Similar to findPosH , but used for vertical motion.unit may be "line" or "page". - The other arguments and the returned value have the same interpretation as they have in findPosH. */ - findPosV(start: CodeMirror.Position, amount: number, unit: string): { line: number; ch: number; hitSide?: boolean; }; - - - /** Change the configuration of the editor. option should the name of an option, and value should be a valid value for that option. */ - setOption(option: string, value: any): void; - - /** Retrieves the current value of the given option for this editor instance. */ - getOption(option: string): any; - - /** Attach an additional keymap to the editor. - This is mostly useful for add - ons that need to register some key handlers without trampling on the extraKeys option. - Maps added in this way have a higher precedence than the extraKeys and keyMap options, and between them, - the maps added earlier have a lower precedence than those added later, unless the bottom argument was passed, - in which case they end up below other keymaps added with this method. */ - addKeyMap(map: any, bottom?: boolean): void; - - /** Disable a keymap added with addKeyMap.Either pass in the keymap object itself , or a string, - which will be compared against the name property of the active keymaps. */ - removeKeyMap(map: any): void; - - /** Enable a highlighting overlay.This is a stateless mini - mode that can be used to add extra highlighting. - For example, the search add - on uses it to highlight the term that's currently being searched. - mode can be a mode spec or a mode object (an object with a token method). The options parameter is optional. If given, it should be an object. - Currently, only the opaque option is recognized. This defaults to off, but can be given to allow the overlay styling, when not null, - to override the styling of the base mode entirely, instead of the two being applied together. */ - addOverlay(mode: any, options?: any): void; - - /** Pass this the exact argument passed for the mode parameter to addOverlay to remove an overlay again. */ - removeOverlay(mode: any): void; - - - /** Retrieve the currently active document from an editor. */ - getDoc(): CodeMirror.Doc; - - /** Attach a new document to the editor. Returns the old document, which is now no longer associated with an editor. */ - swapDoc(doc: CodeMirror.Doc): CodeMirror.Doc; - - - - /** Sets the gutter marker for the given gutter (identified by its CSS class, see the gutters option) to the given value. - Value can be either null, to clear the marker, or a DOM element, to set it. The DOM element will be shown in the specified gutter next to the specified line. */ - setGutterMarker(line: any, gutterID: string, value: HTMLElement): CodeMirror.LineHandle; - - /** Remove all gutter markers in the gutter with the given ID. */ - clearGutter(gutterID: string): void; - - /** Set a CSS class name for the given line.line can be a number or a line handle. - where determines to which element this class should be applied, can can be one of "text" (the text element, which lies in front of the selection), - "background"(a background element that will be behind the selection), - or "wrap" (the wrapper node that wraps all of the line's elements, including gutter elements). - class should be the name of the class to apply. */ - addLineClass(line: any, where: string, _class_: string): CodeMirror.LineHandle; - - /** Remove a CSS class from a line.line can be a line handle or number. - where should be one of "text", "background", or "wrap"(see addLineClass). - class can be left off to remove all classes for the specified node, or be a string to remove only a specific class. */ - removeLineClass(line: any, where: string, class_: string): CodeMirror.LineHandle; - - /** Returns the line number, text content, and marker status of the given line, which can be either a number or a line handle. */ - lineInfo(line: any): { - line: any; - handle: any; - text: string; - /** Object mapping gutter IDs to marker elements. */ - gutterMarks: any; - textClass: string; - bgClass: string; - wrapClass: string; - /** Array of line widgets attached to this line. */ - widgets: any; - }; - - /** Puts node, which should be an absolutely positioned DOM node, into the editor, positioned right below the given { line , ch } position. - When scrollIntoView is true, the editor will ensure that the entire node is visible (if possible). - To remove the widget again, simply use DOM methods (move it somewhere else, or call removeChild on its parent). */ - addWidget(pos: CodeMirror.Position, node: HTMLElement, scrollIntoView: boolean): void; - - /** Adds a line widget, an element shown below a line, spanning the whole of the editor's width, and moving the lines below it downwards. - line should be either an integer or a line handle, and node should be a DOM node, which will be displayed below the given line. - options, when given, should be an object that configures the behavior of the widget. - Note that the widget node will become a descendant of nodes with CodeMirror-specific CSS classes, and those classes might in some cases affect it. */ - addLineWidget(line: any, node: HTMLElement, options?: { - /** Whether the widget should cover the gutter. */ - coverGutter: boolean; - /** Whether the widget should stay fixed in the face of horizontal scrolling. */ - noHScroll: boolean; - /** Causes the widget to be placed above instead of below the text of the line. */ - above: boolean; - /** When true, will cause the widget to be rendered even if the line it is associated with is hidden. */ - showIfHidden: boolean; - }): CodeMirror.LineWidget; - - - /** Programatically set the size of the editor (overriding the applicable CSS rules). - width and height height can be either numbers(interpreted as pixels) or CSS units ("100%", for example). - You can pass null for either of them to indicate that that dimension should not be changed. */ - setSize(width: any, height: any): void; - - /** Scroll the editor to a given(pixel) position.Both arguments may be left as null or undefined to have no effect. */ - scrollTo(x: number, y: number): void; - - /** Get an { left , top , width , height , clientWidth , clientHeight } object that represents the current scroll position, the size of the scrollable area, - and the size of the visible area(minus scrollbars). */ - getScrollInfo(): { - left: any; - top: any; - width: any; - height: any; - clientWidth: any; - clientHeight: any; - }; - - /** Scrolls the given element into view. pos is a { line , ch } position, referring to a given character, null, to refer to the cursor. - The margin parameter is optional. When given, it indicates the amount of pixels around the given area that should be made visible as well. */ - scrollIntoView(pos: CodeMirror.Position, margin?: number): void; - - /** Scrolls the given element into view. pos is a { left , top , right , bottom } object, in editor-local coordinates. - The margin parameter is optional. When given, it indicates the amount of pixels around the given area that should be made visible as well. */ - scrollIntoView(pos: { left: number; top: number; right: number; bottom: number; }, margin: number): void; - - /** Returns an { left , top , bottom } object containing the coordinates of the cursor position. - If mode is "local" , they will be relative to the top-left corner of the editable document. - If it is "page" or not given, they are relative to the top-left corner of the page. - where is a boolean indicating whether you want the start(true) or the end(false) of the selection. */ - cursorCoords(where: boolean, mode: string): { left: number; top: number; bottom: number; }; - - /** Returns an { left , top , bottom } object containing the coordinates of the cursor position. - If mode is "local" , they will be relative to the top-left corner of the editable document. - If it is "page" or not given, they are relative to the top-left corner of the page. - where specifies the precise position at which you want to measure. */ - cursorCoords(where: CodeMirror.Position, mode: string): { left: number; top: number; bottom: number; }; - - /** Returns the position and dimensions of an arbitrary character.pos should be a { line , ch } object. - This differs from cursorCoords in that it'll give the size of the whole character, - rather than just the position that the cursor would have when it would sit at that position. */ - charCoords(pos: CodeMirror.Position, mode: string): { left: number; right: number; top: number; bottom: number; }; - - /** Given an { left , top } object , returns the { line , ch } position that corresponds to it. - The optional mode parameter determines relative to what the coordinates are interpreted. It may be "window" , "page"(the default) , or "local". */ - coordsChar(object: { left: number; top: number; }, mode?: string): CodeMirror.Position; - - /** Returns the line height of the default font for the editor. */ - defaultTextHeight(): number; - - /** Returns the pixel width of an 'x' in the default font for the editor. - (Note that for non - monospace fonts , this is mostly useless, and even for monospace fonts, non - ascii characters might have a different width). */ - defaultCharWidth(): number; - - /** Returns a { from , to } object indicating the start (inclusive) and end (exclusive) of the currently rendered part of the document. - In big documents, when most content is scrolled out of view, CodeMirror will only render the visible part, and a margin around it. - See also the viewportChange event. */ - getViewport(): { from: number; to: number }; - - /** If your code does something to change the size of the editor element (window resizes are already listened for), or unhides it, - you should probably follow up by calling this method to ensure CodeMirror is still looking as intended. */ - refresh(): void; - - - /** Retrieves information about the token the current mode found before the given position (a {line, ch} object). */ - getTokenAt(pos: CodeMirror.Position): { - /** The character(on the given line) at which the token starts. */ - start: number; - /** The character at which the token ends. */ - end: number; - /** The token's string. */ - string: string; - /** The token type the mode assigned to the token, such as "keyword" or "comment" (may also be null). */ - type: string; - /** The mode's state at the end of this token. */ - state: any; - }; - - /** Returns the mode's parser state, if any, at the end of the given line number. - If no line number is given, the state at the end of the document is returned. - This can be useful for storing parsing errors in the state, or getting other kinds of contextual information for a line. */ - getStateAfter(line?: number): any; - - /** CodeMirror internally buffers changes and only updates its DOM structure after it has finished performing some operation. - If you need to perform a lot of operations on a CodeMirror instance, you can call this method with a function argument. - It will call the function, buffering up all changes, and only doing the expensive update after the function returns. - This can be a lot faster. The return value from this method will be the return value of your function. */ - operation(fn: ()=> T): T; - - /** Adjust the indentation of the given line. - The second argument (which defaults to "smart") may be one of: - "prev" Base indentation on the indentation of the previous line. - "smart" Use the mode's smart indentation if available, behave like "prev" otherwise. - "add" Increase the indentation of the line by one indent unit. - "subtract" Reduce the indentation of the line. */ - indentLine(line: number, dir?: string): void; - - - /** Give the editor focus. */ - focus(): void; - - /** Returns the hidden textarea used to read input. */ - getInputField(): HTMLTextAreaElement; - - /** Returns the DOM node that represents the editor, and controls its size. Remove this from your tree to delete an editor instance. */ - getWrapperElement(): HTMLElement; - - /** Returns the DOM node that is responsible for the scrolling of the editor. */ - getScrollerElement(): HTMLElement; - - /** Fetches the DOM node that contains the editor gutters. */ - getGutterElement(): HTMLElement; - - - - /** Events are registered with the on method (and removed with the off method). - These are the events that fire on the instance object. The name of the event is followed by the arguments that will be passed to the handler. - The instance argument always refers to the editor instance. */ - on(eventName: string, handler: (instance: CodeMirror.Editor) => void ): void; - off(eventName: string, handler: (instance: CodeMirror.Editor) => void ): void; - - /** Fires every time the content of the editor is changed. */ - on(eventName: 'change', handler: (instance: CodeMirror.Editor, change: CodeMirror.EditorChangeLinkedList) => void ): void; - off(eventName: 'change', handler: (instance: CodeMirror.Editor, change: CodeMirror.EditorChangeLinkedList) => void ): void; - - /** This event is fired before a change is applied, and its handler may choose to modify or cancel the change. - The changeObj never has a next property, since this is fired for each individual change, and not batched per operation. - Note: you may not do anything from a "beforeChange" handler that would cause changes to the document or its visualization. - Doing so will, since this handler is called directly from the bowels of the CodeMirror implementation, - probably cause the editor to become corrupted. */ - on(eventName: 'beforeChange', handler: (instance: CodeMirror.Editor, change: CodeMirror.EditorChangeCancellable) => void ): void; - off(eventName: 'beforeChange', handler: (instance: CodeMirror.Editor, change: CodeMirror.EditorChangeCancellable) => void ): void; - - /** Will be fired when the cursor or selection moves, or any change is made to the editor content. */ - on(eventName: 'cursorActivity', handler: (instance: CodeMirror.Editor) => void ): void; - off(eventName: 'cursorActivity', handler: (instance: CodeMirror.Editor) => void ): void; - - /** This event is fired before the selection is moved. Its handler may modify the resulting selection head and anchor. - Handlers for this event have the same restriction as "beforeChange" handlers � they should not do anything to directly update the state of the editor. */ - on(eventName: 'beforeSelectionChange', handler: (instance: CodeMirror.Editor, selection: { head: CodeMirror.Position; anchor: CodeMirror.Position; }) => void ): void; - off(eventName: 'beforeSelectionChange', handler: (instance: CodeMirror.Editor, selection: { head: CodeMirror.Position; anchor: CodeMirror.Position; }) => void ): void; - - /** Fires whenever the view port of the editor changes (due to scrolling, editing, or any other factor). - The from and to arguments give the new start and end of the viewport. */ - on(eventName: 'viewportChange', handler: (instance: CodeMirror.Editor, from: number, to: number) => void ): void; - off(eventName: 'viewportChange', handler: (instance: CodeMirror.Editor, from: number, to: number) => void ): void; - - /** Fires when the editor gutter (the line-number area) is clicked. Will pass the editor instance as first argument, - the (zero-based) number of the line that was clicked as second argument, the CSS class of the gutter that was clicked as third argument, - and the raw mousedown event object as fourth argument. */ - on(eventName: 'gutterClick', handler: (instance: CodeMirror.Editor, line: number, gutter: string, clickEvent: Event) => void ): void; - off(eventName: 'gutterClick', handler: (instance: CodeMirror.Editor, line: number, gutter: string, clickEvent: Event) => void ): void; - - /** Fires whenever the editor is focused. */ - on(eventName: 'focus', handler: (instance: CodeMirror.Editor) => void ): void; - off(eventName: 'focus', handler: (instance: CodeMirror.Editor) => void ): void; - - /** Fires whenever the editor is unfocused. */ - on(eventName: 'blur', handler: (instance: CodeMirror.Editor) => void ): void; - off(eventName: 'blur', handler: (instance: CodeMirror.Editor) => void ): void; - - /** Fires when the editor is scrolled. */ - on(eventName: 'scroll', handler: (instance: CodeMirror.Editor) => void ): void; - off(eventName: 'scroll', handler: (instance: CodeMirror.Editor) => void ): void; - - /** Will be fired whenever CodeMirror updates its DOM display. */ - on(eventName: 'update', handler: (instance: CodeMirror.Editor) => void ): void; - off(eventName: 'update', handler: (instance: CodeMirror.Editor) => void ): void; - - /** Fired whenever a line is (re-)rendered to the DOM. Fired right after the DOM element is built, before it is added to the document. - The handler may mess with the style of the resulting element, or add event handlers, but should not try to change the state of the editor. */ - on(eventName: 'renderLine', handler: (instance: CodeMirror.Editor, line: number, element: HTMLElement) => void ): void; - off(eventName: 'renderLine', handler: (instance: CodeMirror.Editor, line: number, element: HTMLElement) => void ): void; - } - - class Doc { - constructor (text: string, mode?: any, firstLineNumber?: number); - - /** Get the current editor content. You can pass it an optional argument to specify the string to be used to separate lines (defaults to "\n"). */ - getValue(seperator?: string): string; - - /** Set the editor content. */ - setValue(content: string): void; - - /** Get the text between the given points in the editor, which should be {line, ch} objects. - An optional third argument can be given to indicate the line separator string to use (defaults to "\n"). */ - getRange(from: Position, to: CodeMirror.Position, seperator?: string): string; - - /** Replace the part of the document between from and to with the given string. - from and to must be {line, ch} objects. to can be left off to simply insert the string at position from. */ - replaceRange(replacement: string, from: CodeMirror.Position, to: CodeMirror.Position): void; - - /** Get the content of line n. */ - getLine(n: number): string; - - /** Set the content of line n. */ - setLine(n: number, text: string): void; - - /** Remove the given line from the document. */ - removeLine(n: number): void; - - /** Get the number of lines in the editor. */ - lineCount(): number; - - /** Get the first line of the editor. This will usually be zero but for linked sub-views, - or documents instantiated with a non-zero first line, it might return other values. */ - firstLine(): number; - - /** Get the last line of the editor. This will usually be lineCount() - 1, but for linked sub-views, it might return other values. */ - lastLine(): number; - - /** Fetches the line handle for the given line number. */ - getLineHandle(num: number): CodeMirror.LineHandle; - - /** Given a line handle, returns the current position of that line (or null when it is no longer in the document). */ - getLineNumber(handle: CodeMirror.LineHandle): number; - - /** Iterate over the whole document, and call f for each line, passing the line handle. - This is a faster way to visit a range of line handlers than calling getLineHandle for each of them. - Note that line handles have a text property containing the line's content (as a string). */ - eachLine(f: (line: CodeMirror.LineHandle) => void ): void; - - /** Iterate over the range from start up to (not including) end, and call f for each line, passing the line handle. - This is a faster way to visit a range of line handlers than calling getLineHandle for each of them. - Note that line handles have a text property containing the line's content (as a string). */ - eachLine(start: number, end: number, f: (line: CodeMirror.LineHandle) => void ): void; - - /** Set the editor content as 'clean', a flag that it will retain until it is edited, and which will be set again when such an edit is undone again. - Useful to track whether the content needs to be saved. */ - markClean(): void; - - /** Returns whether the document is currently clean (not modified since initialization or the last call to markClean). */ - isClean(): boolean; - - - - /** Get the currently selected code. */ - getSelection(): string; - - /** Replace the selection with the given string. By default, the new selection will span the inserted text. - The optional collapse argument can be used to change this � passing "start" or "end" will collapse the selection to the start or end of the inserted text. */ - replaceSelection(replacement: string, collapse?: string): void; - - /** start is a an optional string indicating which end of the selection to return. - It may be "start" , "end" , "head"(the side of the selection that moves when you press shift + arrow), - or "anchor"(the fixed side of the selection).Omitting the argument is the same as passing "head".A { line , ch } object will be returned. */ - getCursor(start?: string): CodeMirror.Position; - - /** Return true if any text is selected. */ - somethingSelected(): boolean; - - /** Set the cursor position.You can either pass a single { line , ch } object , or the line and the character as two separate parameters. */ - setCursor(pos: CodeMirror.Position): void; - - /** Set the selection range.anchor and head should be { line , ch } objects.head defaults to anchor when not given. */ - setSelection(anchor: CodeMirror.Position, head: CodeMirror.Position): void; - - /** Similar to setSelection , but will, if shift is held or the extending flag is set, - move the head of the selection while leaving the anchor at its current place. - pos2 is optional , and can be passed to ensure a region (for example a word or paragraph) will end up selected - (in addition to whatever lies between that region and the current anchor). */ - extendSelection(from: CodeMirror.Position, to?: CodeMirror.Position): void; - - /** Sets or clears the 'extending' flag , which acts similar to the shift key, - in that it will cause cursor movement and calls to extendSelection to leave the selection anchor in place. */ - setExtending(value: boolean): void; - - - /** Retrieve the editor associated with a document. May return null. */ - getEditor(): CodeMirror.Editor; - - - /** Create an identical copy of the given doc. When copyHistory is true , the history will also be copied.Can not be called directly on an editor. */ - copy(copyHistory: boolean): CodeMirror.Doc; - - /** Create a new document that's linked to the target document. Linked documents will stay in sync (changes to one are also applied to the other) until unlinked. */ - linkedDoc(options: { - /** When turned on, the linked copy will share an undo history with the original. - Thus, something done in one of the two can be undone in the other, and vice versa. */ - sharedHist?: boolean; - from?: number; - /** Can be given to make the new document a subview of the original. Subviews only show a given range of lines. - Note that line coordinates inside the subview will be consistent with those of the parent, - so that for example a subview starting at line 10 will refer to its first line as line 10, not 0. */ - to?: number; - /** By default, the new document inherits the mode of the parent. This option can be set to a mode spec to give it a different mode. */ - mode: any; - }): CodeMirror.Doc; - - /** Break the link between two documents. After calling this , changes will no longer propagate between the documents, - and, if they had a shared history, the history will become separate. */ - unlinkDoc(doc: CodeMirror.Doc): void; - - /** Will call the given function for all documents linked to the target document. It will be passed two arguments, - the linked document and a boolean indicating whether that document shares history with the target. */ - iterLinkedDocs(fn: (doc: CodeMirror.Doc, sharedHist: boolean) => void ): void; - - /** Undo one edit (if any undo events are stored). */ - undo(): void; - - /** Redo one undone edit. */ - redo(): void; - - /** Returns an object with {undo, redo } properties , both of which hold integers , indicating the amount of stored undo and redo operations. */ - historySize(): { undo: number; redo: number; }; - - /** Clears the editor's undo history. */ - clearHistory(): void; - - /** Get a(JSON - serializeable) representation of the undo history. */ - getHistory(): any; - - /** Replace the editor's undo history with the one provided, which must be a value as returned by getHistory. - Note that this will have entirely undefined results if the editor content isn't also the same as it was when getHistory was called. */ - setHistory(history: any): void; - - - /** Can be used to mark a range of text with a specific CSS class name. from and to should be { line , ch } objects. */ - markText(from: CodeMirror.Position, to: CodeMirror.Position, options?: CodeMirror.TextMarkerOptions): TextMarker; - - /** Inserts a bookmark, a handle that follows the text around it as it is being edited, at the given position. - A bookmark has two methods find() and clear(). The first returns the current position of the bookmark, if it is still in the document, - and the second explicitly removes the bookmark. */ - setBookmark(pos: CodeMirror.Position, options?: { - /** Can be used to display a DOM node at the current location of the bookmark (analogous to the replacedWith option to markText). */ - widget?: HTMLElement; - - /** By default, text typed when the cursor is on top of the bookmark will end up to the right of the bookmark. - Set this option to true to make it go to the left instead. */ - insertLeft?: boolean; - }): CodeMirror.TextMarker; - - /** Returns an array of all the bookmarks and marked ranges present at the given position. */ - findMarksAt(pos: CodeMirror.Position): TextMarker[]; - - /** Returns an array containing all marked ranges in the document. */ - getAllMarks(): CodeMirror.TextMarker[]; - - - /** Gets the mode object for the editor. Note that this is distinct from getOption("mode"), which gives you the mode specification, - rather than the resolved, instantiated mode object. */ - getMode(): any; - - /** Calculates and returns a { line , ch } object for a zero-based index whose value is relative to the start of the editor's text. - If the index is out of range of the text then the returned object is clipped to start or end of the text respectively. */ - posFromIndex(index: number): CodeMirror.Position; - - /** The reverse of posFromIndex. */ - indexFromPos(object: CodeMirror.Position): number; - - } - - interface LineHandle { - text: string; - } - - interface TextMarker { - /** Remove the mark. */ - clear(): void; - - /** Returns a {from, to} object (both holding document positions), indicating the current position of the marked range, - or undefined if the marker is no longer in the document. */ - find(): CodeMirror.Position; - - /** Returns an object representing the options for the marker. If copyWidget is given true, it will clone the value of the replacedWith option, if any. */ - getOptions(copyWidget: boolean): CodeMirror.TextMarkerOptions; - } - - interface LineWidget { - /** Removes the widget. */ - clear(): void; - - /** Call this if you made some change to the widget's DOM node that might affect its height. - It'll force CodeMirror to update the height of the line that contains the widget. */ - changed(): void; - } - - interface EditorChange { - /** Position (in the pre-change coordinate system) where the change started. */ - from: CodeMirror.Position; - /** Position (in the pre-change coordinate system) where the change ended. */ - to: CodeMirror.Position; - /** Array of strings representing the text that replaced the changed range (split by line). */ - text: string[]; - /** Text that used to be between from and to, which is overwritten by this change. */ - removed: string[]; - } - - interface EditorChangeLinkedList extends CodeMirror.EditorChange { - /** Points to another change object (which may point to another, etc). */ - next?: CodeMirror.EditorChangeLinkedList; - } - - interface EditorChangeCancellable extends CodeMirror.EditorChange { - /** may be used to modify the change. All three arguments to update are optional, and can be left off to leave the existing value for that field intact. */ - update(from?: CodeMirror.Position, to?: CodeMirror.Position, text?: string): void; - - cancel(): void; - } - - interface Position { - ch: number; - line: number; - } - - interface EditorConfiguration { - /** string| The starting value of the editor. Can be a string, or a document object. */ - value?: any; - - /** string|object. The mode to use. When not given, this will default to the first mode that was loaded. - It may be a string, which either simply names the mode or is a MIME type associated with the mode. - Alternatively, it may be an object containing configuration options for the mode, - with a name property that names the mode (for example {name: "javascript", json: true}). */ - mode?: any; - - /** The theme to style the editor with. You must make sure the CSS file defining the corresponding .cm-s-[name] styles is loaded. - The default is "default". */ - theme?: string; - - /** How many spaces a block (whatever that means in the edited language) should be indented. The default is 2. */ - indentUnit?: number; - - /** Whether to use the context-sensitive indentation that the mode provides (or just indent the same as the line before). Defaults to true. */ - smartIndent?: boolean; - - /** The width of a tab character. Defaults to 4. */ - tabSize?: number; - - /** Whether, when indenting, the first N*tabSize spaces should be replaced by N tabs. Default is false. */ - indentWithTabs?: boolean; - - /** Configures whether the editor should re-indent the current line when a character is typed - that might change its proper indentation (only works if the mode supports indentation). Default is true. */ - electricChars?: boolean; - - /** Determines whether horizontal cursor movement through right-to-left (Arabic, Hebrew) text - is visual (pressing the left arrow moves the cursor left) - or logical (pressing the left arrow moves to the next lower index in the string, which is visually right in right-to-left text). - The default is false on Windows, and true on other platforms. */ - rtlMoveVisually?: boolean; - - /** Configures the keymap to use. The default is "default", which is the only keymap defined in codemirror.js itself. - Extra keymaps are found in the keymap directory. See the section on keymaps for more information. */ - keyMap?: string; - - /** Can be used to specify extra keybindings for the editor, alongside the ones defined by keyMap. Should be either null, or a valid keymap value. */ - extraKeys?: any; - - /** Whether CodeMirror should scroll or wrap for long lines. Defaults to false (scroll). */ - lineWrapping?: boolean; - - /** Whether to show line numbers to the left of the editor. */ - lineNumbers?: boolean; - - /** At which number to start counting lines. Default is 1. */ - firstLineNumber?: number; - - /** A function used to format line numbers. The function is passed the line number, and should return a string that will be shown in the gutter. */ - lineNumberFormatter?: (line: number) => string; - - /** Can be used to add extra gutters (beyond or instead of the line number gutter). - Should be an array of CSS class names, each of which defines a width (and optionally a background), - and which will be used to draw the background of the gutters. - May include the CodeMirror-linenumbers class, in order to explicitly set the position of the line number gutter - (it will default to be to the right of all other gutters). These class names are the keys passed to setGutterMarker. */ - gutters?: string[]; - - /** Determines whether the gutter scrolls along with the content horizontally (false) - or whether it stays fixed during horizontal scrolling (true, the default). */ - fixedGutter?: boolean; - - /** boolean|string. This disables editing of the editor content by the user. If the special value "nocursor" is given (instead of simply true), focusing of the editor is also disallowed. */ - readOnly?: any; - - /**Whether the cursor should be drawn when a selection is active. Defaults to false. */ - showCursorWhenSelecting?: boolean; - - /** The maximum number of undo levels that the editor stores. Defaults to 40. */ - undoDepth?: number; - - /** The period of inactivity (in milliseconds) that will cause a new history event to be started when typing or deleting. Defaults to 500. */ - historyEventDelay?: number; - - /** The tab index to assign to the editor. If not given, no tab index will be assigned. */ - tabindex?: number; - - /** Can be used to make CodeMirror focus itself on initialization. Defaults to off. - When fromTextArea is used, and no explicit value is given for this option, it will be set to true when either the source textarea is focused, - or it has an autofocus attribute and no other element is focused. */ - autofocus?: boolean; - - /** Controls whether drag-and - drop is enabled. On by default. */ - dragDrop?: boolean; - - /** When given , this will be called when the editor is handling a dragenter , dragover , or drop event. - It will be passed the editor instance and the event object as arguments. - The callback can choose to handle the event itself , in which case it should return true to indicate that CodeMirror should not do anything further. */ - onDragEvent?: (instance: CodeMirror.Editor, event: Event) => boolean; - - /** This provides a rather low - level hook into CodeMirror's key handling. - If provided, this function will be called on every keydown, keyup, and keypress event that CodeMirror captures. - It will be passed two arguments, the editor instance and the key event. - This key event is pretty much the raw key event, except that a stop() method is always added to it. - You could feed it to, for example, jQuery.Event to further normalize it. - This function can inspect the key event, and handle it if it wants to. - It may return true to tell CodeMirror to ignore the event. - Be wary that, on some browsers, stopping a keydown does not stop the keypress from firing, whereas on others it does. - If you respond to an event, you should probably inspect its type property and only do something when it is keydown - (or keypress for actions that need character data). */ - onKeyEvent?: (instance: CodeMirror.Editor, event: Event) => boolean; - - /** Half - period in milliseconds used for cursor blinking. The default blink rate is 530ms. */ - cursorBlinkRate?: number; - - /** Determines the height of the cursor. Default is 1 , meaning it spans the whole height of the line. - For some fonts (and by some tastes) a smaller height (for example 0.85), - which causes the cursor to not reach all the way to the bottom of the line, looks better */ - cursorHeight?: number; - - /** Highlighting is done by a pseudo background - thread that will work for workTime milliseconds, - and then use timeout to sleep for workDelay milliseconds. - The defaults are 200 and 300, you can change these options to make the highlighting more or less aggressive. */ - workTime?: number; - - /** See workTime. */ - workDelay?: number; - - /** Indicates how quickly CodeMirror should poll its input textarea for changes(when focused). - Most input is captured by events, but some things, like IME input on some browsers, don't generate events that allow CodeMirror to properly detect it. - Thus, it polls. Default is 100 milliseconds. */ - pollInterval?: number; - - /** By default, CodeMirror will combine adjacent tokens into a single span if they have the same class. - This will result in a simpler DOM tree, and thus perform better. With some kinds of styling(such as rounded corners), - this will change the way the document looks. You can set this option to false to disable this behavior. */ - flattenSpans?: boolean; - - /** When highlighting long lines, in order to stay responsive, the editor will give up and simply style - the rest of the line as plain text when it reaches a certain position. The default is 10000. - You can set this to Infinity to turn off this behavior. */ - maxHighlightLength?: number; - - /** Specifies the amount of lines that are rendered above and below the part of the document that's currently scrolled into view. - This affects the amount of updates needed when scrolling, and the amount of work that such an update does. - You should usually leave it at its default, 10. Can be set to Infinity to make sure the whole document is always rendered, - and thus the browser's text search works on it. This will have bad effects on performance of big documents. */ - viewportMargin?: number; - } - - interface TextMarkerOptions { - /** Assigns a CSS class to the marked stretch of text. */ - className?: string; - - /** Determines whether text inserted on the left of the marker will end up inside or outside of it. */ - inclusiveLeft?: boolean; - - /** Like inclusiveLeft , but for the right side. */ - inclusiveRight?: boolean; - - /** Atomic ranges act as a single unit when cursor movement is concerned � i.e. it is impossible to place the cursor inside of them. - In atomic ranges, inclusiveLeft and inclusiveRight have a different meaning � they will prevent the cursor from being placed - respectively directly before and directly after the range. */ - atomic?: boolean; - - /** Collapsed ranges do not show up in the display.Setting a range to be collapsed will automatically make it atomic. */ - collapsed?: boolean; - - /** When enabled, will cause the mark to clear itself whenever the cursor enters its range. - This is mostly useful for text - replacement widgets that need to 'snap open' when the user tries to edit them. - The "clear" event fired on the range handle can be used to be notified when this happens. */ - clearOnEnter?: boolean; - - /** Use a given node to display this range.Implies both collapsed and atomic. - The given DOM node must be an inline element(as opposed to a block element). */ - replacedWith?: HTMLElement; - - /** A read - only span can, as long as it is not cleared, not be modified except by calling setValue to reset the whole document. - Note: adding a read - only span currently clears the undo history of the editor, - because existing undo events being partially nullified by read - only spans would corrupt the history (in the current implementation). */ - readOnly?: boolean; - - /** When set to true (default is false), adding this marker will create an event in the undo history that can be individually undone(clearing the marker). */ - addToHistory?: boolean; - - /** Can be used to specify an extra CSS class to be applied to the leftmost span that is part of the marker. */ - startStyle?: string; - - /** Equivalent to startStyle, but for the rightmost span. */ - endStyle?: string; - - /** When the target document is linked to other documents, you can set shared to true to make the marker appear in all documents. - By default, a marker appears only in its target document. */ - shared?: boolean; - } -} diff --git a/lib/typings/d3/d3.d.ts b/lib/typings/d3/d3.d.ts deleted file mode 100644 index 0e5cddaae..000000000 --- a/lib/typings/d3/d3.d.ts +++ /dev/null @@ -1,3459 +0,0 @@ -// Type definitions for d3JS -// Project: http://d3js.org/ -// Definitions by: Boris Yankov -// Definitions: https://github.com/borisyankov/DefinitelyTyped - -declare module D3 { - export interface Selectors { - /** - * Select an element from the current document - */ - select: { - /** - * Returns the empty selection - */ - (): _Selection; - /** - * Selects the first element that matches the specified selector string - * - * @param selector Selection String to match - */ - (selector: string): _Selection; - /** - * Selects the specified node - * - * @param element Node element to select - */ - (element: EventTarget): _Selection; - }; - - /** - * Select multiple elements from the current document - */ - selectAll: { - /** - * Selects all elements that match the specified selector - * - * @param selector Selection String to match - */ - (selector: string): _Selection; - /** - * Selects the specified array of elements - * - * @param elements Array of node elements to select - */ - (elements: EventTarget[]): _Selection; - }; - } - - export interface D3Event extends Event{ - dx: number; - dy: number; - clientX: number; - clientY: number; - translate: number[]; - scale: number; - sourceEvent: D3Event; - x: number; - y: number; - keyCode: number; - altKey: any; - type: string; - } - - export interface Base extends Selectors { - /** - * Create a behavior - */ - behavior: Behavior.Behavior; - /** - * Access the current user event for interaction - */ - event: D3Event; - - /** - * Compare two values for sorting. - * Returns -1 if a is less than b, or 1 if a is greater than b, or 0 - * - * @param a First value - * @param b Second value - */ - ascending(a: T, b: T): number; - /** - * Compare two values for sorting. - * Returns -1 if a is greater than b, or 1 if a is less than b, or 0 - * - * @param a First value - * @param b Second value - */ - descending(a: T, b: T): number; - /** - * Find the minimum value in an array - * - * @param arr Array to search - * @param map Accsessor function - */ - min(arr: T[], map: (v?: T, i?: number) => U): U; - /** - * Find the minimum value in an array - * - * @param arr Array to search - */ - min(arr: T[]): T; - /** - * Find the maximum value in an array - * - * @param arr Array to search - * @param map Accsessor function - */ - max(arr: T[], map: (v?: T, i?: number) => U): U; - /** - * Find the maximum value in an array - * - * @param arr Array to search - */ - max(arr: T[]): T; - /** - * Find the minimum and maximum value in an array - * - * @param arr Array to search - * @param map Accsessor function - */ - extent(arr: T[], map: (v: T) => U): U[]; - /** - * Find the minimum and maximum value in an array - * - * @param arr Array to search - */ - extent(arr: T[]): T[]; - /** - * Compute the sum of an array of numbers - * - * @param arr Array to search - * @param map Accsessor function - */ - sum(arr: T[], map: (v: T) => number): number; - /** - * Compute the sum of an array of numbers - * - * @param arr Array to search - */ - sum(arr: number[]): number; - /** - * Compute the arithmetic mean of an array of numbers - * - * @param arr Array to search - * @param map Accsessor function - */ - mean(arr: T[], map: (v: T) => number): number; - /** - * Compute the arithmetic mean of an array of numbers - * - * @param arr Array to search - */ - mean(arr: number[]): number; - /** - * Compute the median of an array of numbers (the 0.5-quantile). - * - * @param arr Array to search - * @param map Accsessor function - */ - median(arr: T[], map: (v: T) => number): number; - /** - * Compute the median of an array of numbers (the 0.5-quantile). - * - * @param arr Array to search - */ - median(arr: number[]): number; - /** - * Compute a quantile for a sorted array of numbers. - * - * @param arr Array to search - * @param p The quantile to return - */ - quantile: (arr: number[], p: number) => number; - /** - * Locate the insertion point for x in array to maintain sorted order - * - * @param arr Array to search - * @param x Value to search for insertion point - * @param low Minimum value of array subset - * @param hihg Maximum value of array subset - */ - bisect(arr: T[], x: T, low?: number, high?: number): number; - /** - * Locate the insertion point for x in array to maintain sorted order - * - * @param arr Array to search - * @param x Value to serch for insertion point - * @param low Minimum value of array subset - * @param high Maximum value of array subset - */ - bisectLeft(arr: T[], x: T, low?: number, high?: number): number; - /** - * Locate the insertion point for x in array to maintain sorted order - * - * @param arr Array to search - * @param x Value to serch for insertion point - * @param low Minimum value of array subset - * @param high Maximum value of array subset - */ - bisectRight(arr: T[], x: T, low?: number, high?: number): number; - /** - * Bisect using an accessor. - * - * @param accessor Accessor function - */ - bisector(accessor: (data: any, index: number) => any): any; - /** - * Randomize the order of an array. - * - * @param arr Array to randomize - */ - shuffle(arr: T[]): T[]; - /** - * Reorder an array of elements according to an array of indexes - * - * @param arr Array to reorder - * @param indexes Array containing the order the elements should be returned in - */ - permute(arr: any[], indexes: any[]): any[]; - /** - * Transpose a variable number of arrays. - * - * @param arrs Arrays to transpose - */ - zip(...arrs: any[]): any[]; - /** - * Parse the given 2D affine transform string, as defined by SVG's transform attribute. - * - * @param definition 2D affine transform string - */ - transform(definition: string): any; - /** - * Transpose an array of arrays. - * - * @param matrix Two dimensional array to transpose - */ - transpose(matrix: any[]): any[]; - /** - * Creates an array containing tuples of adjacent pairs - * - * @param arr An array containing entries to pair - * @returns any[][] An array of 2-element tuples for each pair - */ - pairs(arr: any[]): any[][]; - /** - * List the keys of an associative array. - * - * @param map Array of objects to get the key values from - */ - keys(map: any): string[]; - /** - * List the values of an associative array. - * - * @param map Array of objects to get the values from - */ - values(map: any): any[]; - /** - * List the key-value entries of an associative array. - * - * @param map Array of objects to get the key-value pairs from - */ - entries(map: any): any[]; - /** - * merge multiple arrays into one array - * - * @param map Arrays to merge - */ - merge(...map: any[]): any[]; - /** - * Generate a range of numeric values. - */ - range: { - /** - * Generate a range of numeric values from 0. - * - * @param stop Value to generate the range to - * @param step Step between each value - */ - (stop: number, step?: number): number[]; - /** - * Generate a range of numeric values. - * - * @param start Value to start - * @param stop Value to generate the range to - * @param step Step between each value - */ - (start: number, stop?: number, step?: number): number[]; - }; - /** - * Create new nest operator - */ - nest(): Nest; - /** - * Request a resource using XMLHttpRequest. - */ - xhr: { - /** - * Creates an asynchronous request for specified url - * - * @param url Url to request - * @param callback Function to invoke when resource is loaded or the request fails - */ - (url: string, callback?: (xhr: XMLHttpRequest) => void ): Xhr; - /** - * Creates an asynchronous request for specified url - * - * @param url Url to request - * @param mime MIME type to request - * @param callback Function to invoke when resource is loaded or the request fails - */ - (url: string, mime: string, callback?: (xhr: XMLHttpRequest) => void ): Xhr; - }; - /** - * Request a text file - */ - text: { - /** - * Request a text file - * - * @param url Url to request - * @param callback Function to invoke when resource is loaded or the request fails - */ - (url: string, callback?: (response: string) => void ): Xhr; - /** - * Request a text file - * - * @param url Url to request - * @param mime MIME type to request - * @param callback Function to invoke when resource is loaded or the request fails - */ - (url: string, mime: string, callback?: (response: string) => void ): Xhr; - }; - /** - * Request a JSON blob - * - * @param url Url to request - * @param callback Function to invoke when resource is loaded or the request fails - */ - json: (url: string, callback?: (error: any, data: any) => void ) => Xhr; - /** - * Request an HTML document fragment. - */ - xml: { - /** - * Request an HTML document fragment. - * - * @param url Url to request - * @param callback Function to invoke when resource is loaded or the request fails - */ - (url: string, callback?: (response: Document) => void ): Xhr; - /** - * Request an HTML document fragment. - * - * @param url Url to request - * @param mime MIME type to request - * @param callback Function to invoke when resource is loaded or the request fails - */ - (url: string, mime: string, callback?: (response: Document) => void ): Xhr; - }; - /** - * Request an XML document fragment. - * - * @param url Url to request - * @param callback Function to invoke when resource is loaded or the request fails - */ - html: (url: string, callback?: (response: DocumentFragment) => void ) => Xhr; - /** - * Request a comma-separated values (CSV) file. - */ - csv: Dsv; - /** - * Request a tab-separated values (TSV) file - */ - tsv: Dsv; - /** - * Time Functions - */ - time: Time.Time; - /** - * Scales - */ - scale: Scale.ScaleBase; - /* - * Interpolate two values - */ - interpolate: Transition.BaseInterpolate; - /* - * Interpolate two numbers - */ - interpolateNumber: Transition.BaseInterpolate; - /* - * Interpolate two integers - */ - interpolateRound: Transition.BaseInterpolate; - /* - * Interpolate two strings - */ - interpolateString: Transition.BaseInterpolate; - /* - * Interpolate two RGB colors - */ - interpolateRgb: Transition.BaseInterpolate; - /* - * Interpolate two HSL colors - */ - interpolateHsl: Transition.BaseInterpolate; - /* - * Interpolate two HCL colors - */ - interpolateHcl: Transition.BaseInterpolate; - /* - * Interpolate two L*a*b* colors - */ - interpolateLab: Transition.BaseInterpolate; - /* - * Interpolate two arrays of values - */ - interpolateArray: Transition.BaseInterpolate; - /* - * Interpolate two arbitary objects - */ - interpolateObject: Transition.BaseInterpolate; - /* - * Interpolate two 2D matrix transforms - */ - interpolateTransform: Transition.BaseInterpolate; - /* - * The array of built-in interpolator factories - */ - interpolators: Transition.InterpolateFactory[]; - /** - * Layouts - */ - layout: Layout.Layout; - /** - * Svg's - */ - svg: Svg.Svg; - /** - * Random number generators - */ - random: Random; - /** - * Create a function to format a number as a string - * - * @param specifier The format specifier to use - */ - format(specifier: string): (value: number) => string; - /** - * Returns the SI prefix for the specified value at the specified precision - */ - formatPrefix(value: number, precision?: number): MetricPrefix; - /** - * The version of the d3 library - */ - version: string; - /** - * Returns the root selection - */ - selection(): _Selection; - ns: { - /** - * The map of registered namespace prefixes - */ - prefix: { - svg: string; - xhtml: string; - xlink: string; - xml: string; - xmlns: string; - }; - /** - * Qualifies the specified name - */ - qualify(name: string): { space: string; local: string; }; - }; - /** - * Returns a built-in easing function of the specified type - */ - ease: (type: string, ...arrs: any[]) => D3.Transition.Transition; - /** - * Constructs a new RGB color. - */ - rgb: { - /** - * Constructs a new RGB color with the specified r, g and b channel values - */ - (r: number, g: number, b: number): D3.Color.RGBColor; - /** - * Constructs a new RGB color by parsing the specified color string - */ - (color: string): D3.Color.RGBColor; - }; - /** - * Constructs a new HCL color. - */ - hcl: { - /** - * Constructs a new HCL color. - */ - (h: number, c: number, l: number): Color.HCLColor; - /** - * Constructs a new HCL color by parsing the specified color string - */ - (color: string): Color.HCLColor; - }; - /** - * Constructs a new HSL color. - */ - hsl: { - /** - * Constructs a new HSL color with the specified hue h, saturation s and lightness l - */ - (h: number, s: number, l: number): Color.HSLColor; - /** - * Constructs a new HSL color by parsing the specified color string - */ - (color: string): Color.HSLColor; - }; - /** - * Constructs a new RGB color. - */ - lab: { - /** - * Constructs a new LAB color. - */ - (l: number, a: number, b: number): Color.LABColor; - /** - * Constructs a new LAB color by parsing the specified color string - */ - (color: string): Color.LABColor; - }; - geo: Geo.Geo; - geom: Geom.Geom; - /** - * gets the mouse position relative to a specified container. - */ - mouse(container: any): number[]; - /** - * gets the touch positions relative to a specified container. - */ - touches(container: any): number[][]; - - /** - * If the specified value is a function, returns the specified value. - * Otherwise, returns a function that returns the specified value. - */ - functor(value: (p : R) => T): (p : R) => T; - functor(value: T): (p : any) => T; - - map: { - (): Map; - (object: {[key: string]: T; }): Map; - (map: Map): Map; - (array: T[]): Map; - (array: T[], keyFn: (object: T, index?: number) => string): Map; - }; - set: { - (): Set; - (array: T[]): Set; - }; - dispatch(...types: string[]): Dispatch; - rebind(target: any, source: any, ...names: any[]): any; - requote(str: string): string; - timer: { - (funct: () => boolean, delay?: number, mark?: number): void; - flush(): void; - } - transition(): Transition.Transition; - - round(x: number, n: number): number; - } - - export interface Dispatch { - [event: string]: any; - on: { - (type: string): any; - (type: string, listener: any): any; - } - } - - export interface MetricPrefix { - /** - * the scale function, for converting numbers to the appropriate prefixed scale. - */ - scale: (d: number) => number; - /** - * the prefix symbol - */ - symbol: string; - } - - export interface Xhr { - /** - * Get or set request header - */ - header: { - /** - * Get the value of specified request header - * - * @param name Name of header to get the value for - */ - (name: string): string; - /** - * Set the value of specified request header - * - * @param name Name of header to set the value for - * @param value Value to set the header to - */ - (name: string, value: string): Xhr; - }; - /** - * Get or set MIME Type - */ - mimeType: { - /** - * Get the current MIME Type - */ - (): string; - /** - * Set the MIME Type for the request - * - * @param type The MIME type for the request - */ - (type: string): Xhr; - }; - /* - * Get or Set the function used to map the response to the associated data value - */ - response: { - /** - * Get function used to map the response to the associated data value - */ - (): (xhr: XMLHttpRequest) => any; - /** - * Set function used to map the response to the associated data value - * - * @param value The function used to map the response to a data value - */ - (value: (xhr: XMLHttpRequest) => any): Xhr; - }; - /** - * Issue the request using the GET method - * - * @param callback Function to invoke on completion of request - */ - get(callback?: (xhr: XMLHttpRequest) => void ): Xhr; - /** - * Issue the request using the POST method - */ - post: { - /** - * Issue the request using the POST method - * - * @param callback Function to invoke on completion of request - */ - (callback?: (xhr: XMLHttpRequest) => void ): Xhr; - /** - * Issue the request using the POST method - * - * @param data Data to post back in the request - * @param callback Function to invoke on completion of request - */ - (data: any, callback?: (xhr: XMLHttpRequest) => void ): Xhr; - }; - /** - * Issues this request using the specified method - */ - send: { - /** - * Issues this request using the specified method - * - * @param method Method to use to make the request - * @param callback Function to invoke on completion of request - */ - (method: string, callback?: (xhr: XMLHttpRequest) => void ): Xhr; - /** - * Issues this request using the specified method - * - * @param method Method to use to make the request - * @param data Data to post back in the request - * @param callback Function to invoke on completion of request - */ - (method: string, data: any, callback?: (xhr: XMLHttpRequest) => void ): Xhr; - }; - /** - * Aborts this request, if it is currently in-flight - */ - abort(): Xhr; - /** - * Registers a listener to receive events - * - * @param type Enent name to attach the listener to - * @param listener Function to attach to event - */ - on: (type: string, listener: (data: any, index?: number) => any) => Xhr; - } - - export interface Dsv { - /** - * Request a delimited values file - * - * @param url Url to request - * @param callback Function to invoke when resource is loaded or the request fails - */ - (url: string, callback?: (error: any, response: any[]) => void ): Xhr; - /** - * Parse a delimited string into objects using the header row. - * - * @param string delimited formatted string to parse - * @param accessor to modify properties of each row - */ - parse(string: string, accessor?: (row: any, index?: number) => any): any[]; - /** - * Parse a delimited string into tuples, ignoring the header row. - * - * @param string delimited formatted string to parse - */ - parseRows(string: string, accessor: (row: any[], index: number) => any): any; - /** - * Format an array of tuples into a delimited string. - * - * @param rows Array to convert to a delimited string - */ - format(rows: any[]): string; - } - - export interface _Selection extends Selectors, Array { - attr: { - (name: string): string; - (name: string, value: any): _Selection; - (name: string, valueFunction: (data: T, index: number) => any): _Selection; - (attrValueMap: Object): _Selection; - }; - - classed: { - (name: string): boolean; - (name: string, value: any): _Selection; - (name: string, valueFunction: (data: T, index: number) => any): _Selection; - (classValueMap: Object): _Selection; - }; - - style: { - (name: string): string; - (name: string, value: any, priority?: string): _Selection; - (name: string, valueFunction: (data: T, index: number) => any, priority?: string): _Selection; - (styleValueMap: Object): _Selection; - }; - - property: { - (name: string): void; - (name: string, value: any): _Selection; - (name: string, valueFunction: (data: T, index: number) => any): _Selection; - (propertyValueMap: Object): _Selection; - }; - - text: { - (): string; - (value: any): _Selection; - (valueFunction: (data: T, index: number) => any): _Selection; - }; - - html: { - (): string; - (value: any): _Selection; - (valueFunction: (data: T, index: number) => any): _Selection; - }; - - append: (name: string) => _Selection; - insert: (name: string, before: string) => _Selection; - remove: () => _Selection; - empty: () => boolean; - - data: { - (values: (data: T, index?: number) => U[], key?: (data: U, index?: number) => any): _UpdateSelection; - (values: U[], key?: (data: U, index?: number) => any): _UpdateSelection; - (): T[]; - }; - - datum: { - /** - * Sets the element's bound data to the return value of the specified function evaluated - * for each selected element. - * Unlike the D3.Selection.data method, this method does not compute a join (and thus - * does not compute enter and exit selections). - * @param values The function to be evaluated for each selected element, being passed the - * previous datum d and the current index i, with the this context as the current DOM - * element. The function is then used to set each element's data. A null value will - * delete the bound data. This operator has no effect on the index. - */ - (values: (data: U, index: number) => any): _UpdateSelection; - /** - * Sets the element's bound data to the specified value on all selected elements. - * Unlike the D3.Selection.data method, this method does not compute a join (and thus - * does not compute enter and exit selections). - * @param values The same data to be given to all elements. - */ - (values: U): _UpdateSelection; - /** - * Returns the bound datum for the first non-null element in the selection. - * This is generally useful only if you know the selection contains exactly one element. - */ - (): T; - }; - - filter: { - (filter: (data: T, index: number) => boolean, thisArg?: any): _UpdateSelection; - (filter: string): _UpdateSelection; - }; - - call(callback: (selection: _Selection, ...args: any[]) => void, ...args: any[]): _Selection; - each(eachFunction: (data: T, index: number) => any): _Selection; - on: { - (type: string): (data: any, index: number) => any; - (type: string, listener: (data: any, index: number) => any, capture?: boolean): _Selection; - }; - - /** - * Returns the total number of elements in the current selection. - */ - size(): number; - - /** - * Starts a transition for the current selection. Transitions behave much like selections, - * except operators animate smoothly over time rather than applying instantaneously. - */ - transition(): Transition.Transition; - - /** - * Sorts the elements in the current selection according to the specified comparator - * function. - * - * @param comparator a comparison function, which will be passed two data elements a and b - * to compare, and should return either a negative, positive, or zero value to indicate - * their relative order. - */ - sort(comparator?: (a: T, b: T) => number): this; - - /** - * Re-inserts elements into the document such that the document order matches the selection - * order. This is equivalent to calling sort() if the data is already sorted, but much - * faster. - */ - order: () => _Selection; - - /** - * Returns the first non-null element in the current selection. If the selection is empty, - * returns null. - */ - node: () => E; - } - - export interface Selection extends _Selection { } - - export interface _EnterSelection { - append: (name: string) => _Selection; - insert: (name: string, before?: string) => _Selection; - select: (selector: string) => _Selection; - empty: () => boolean; - node: () => Element; - call: (callback: (selection: _EnterSelection) => void) => _EnterSelection; - size: () => number; - } - - export interface EnterSelection extends _EnterSelection { } - - export interface _UpdateSelection extends _Selection { - enter: () => _EnterSelection; - update: () => _Selection; - exit: () => _Selection; - } - - export interface UpdateSelection extends _UpdateSelection { } - - export interface NestKeyValue { - key: string; - values: any; - } - - export interface Nest { - key(keyFunction: (data: any, index: number) => string): Nest; - sortKeys(comparator: (d1: any, d2: any) => number): Nest; - sortValues(comparator: (d1: any, d2: any) => number): Nest; - rollup(rollupFunction: (data: any, index: number) => any): Nest; - map(values: any[], mapType?: any): any; - entries(values: any[]): NestKeyValue[]; - } - - export interface MapKeyValue { - key: string; - value: T; - } - - export interface Map { - has(key: string): boolean; - get(key: string): T; - set(key: string, value: T): T; - remove(key: string): boolean; - keys(): string[]; - values(): T[]; - entries(): MapKeyValue[]; - forEach(func: (key: string, value: T) => void ): void; - empty(): boolean; - size(): number; - } - - export interface Set { - has(value: T): boolean; - add(value: T): T; - remove(value: T): boolean; - values(): string[]; - forEach(func: (value: string) => void ): void; - empty(): boolean; - size(): number; - } - - export interface Random { - /** - * Returns a function for generating random numbers with a normal distribution - * - * @param mean The expected value of the generated pseudorandom numbers - * @param deviation The given standard deviation - */ - normal(mean?: number, deviation?: number): () => number; - /** - * Returns a function for generating random numbers with a log-normal distribution - * - * @param mean The expected value of the generated pseudorandom numbers - * @param deviation The given standard deviation - */ - logNormal(mean?: number, deviation?: number): () => number; - /** - * Returns a function for generating random numbers with an Irwin-Hall distribution - * - * @param count The number of independent variables - */ - irwinHall(count: number): () => number; - } - - // Transitions - export module Transition { - export interface Transition { - duration: { - (duration: number): Transition; - (duration: (data: any, index: number) => any): Transition; - }; - delay: { - (delay: number): Transition; - (delay: (data: any, index: number) => any): Transition; - }; - attr: { - (name: string): string; - (name: string, value: any): Transition; - (name: string, valueFunction: (data: any, index: number) => any): Transition; - (attrValueMap : any): Transition; - }; - style: { - (name: string): string; - (name: string, value: any, priority?: string): Transition; - (name: string, valueFunction: (data: any, index: number) => any, priority?: string): Transition; - }; - call(callback: (transition: Transition, ...args: any[]) => void, ...args: any[]): Transition; - /** - * Select an element from the current document - */ - select: { - /** - * Selects the first element that matches the specified selector string - * - * @param selector Selection String to match - */ - (selector: string): Transition; - /** - * Selects the specified node - * - * @param element Node element to select - */ - (element: EventTarget): Transition; - }; - - /** - * Select multiple elements from the current document - */ - selectAll: { - /** - * Selects all elements that match the specified selector - * - * @param selector Selection String to match - */ - (selector: string): Transition; - /** - * Selects the specified array of elements - * - * @param elements Array of node elements to select - */ - (elements: EventTarget[]): Transition; - } - each: { - /** - * Immediately invokes the specified function for each element in the current - * transition, passing in the current datum and index, with the this context - * of the current DOM element. Similar to D3.Selection.each. - * - * @param eachFunction The function to be invoked for each element in the - * current transition, passing in the current datum and index, with the this - * context of the current DOM element. - */ - (eachFunction: (data: any, index: number) => any): Transition; - /** - * Adds a listener for transition events, supporting "start", "end" and - * "interrupt" events. The listener will be invoked for each individual - * element in the transition. - * - * @param type Type of transition event. Supported values are "start", "end" - * and "interrupt". - * @param listener The listener to be invoked for each individual element in - * the transition. - */ - (type: string, listener: (data: any, index: number) => any): Transition; - } - transition: () => Transition; - ease: (value: string, ...arrs: any[]) => Transition; - attrTween(name: string, tween: (d: any, i: number, a: any) => BaseInterpolate): Transition; - styleTween(name: string, tween: (d: any, i: number, a: any) => BaseInterpolate, priority?: string): Transition; - text: { - (text: string): Transition; - (text: (d: any, i: number) => string): Transition; - } - tween(name: string, factory: InterpolateFactory): Transition; - filter: { - (selector: string): Transition; - (selector: (data: any, index: number) => boolean): Transition; - }; - remove(): Transition; - } - - export interface InterpolateFactory { - (a?: any, b?: any): BaseInterpolate; - } - - export interface BaseInterpolate { - (a: any, b?: any): any; - } - - export interface Interpolate { - (t: any): any; - } - } - - //Time - export module Time { - export interface Time { - second: Interval; - minute: Interval; - hour: Interval; - day: Interval; - week: Interval; - sunday: Interval; - monday: Interval; - tuesday: Interval; - wednesday: Interval; - thursday: Interval; - friday: Interval; - saturday: Interval; - month: Interval; - year: Interval; - - seconds: Range; - minutes: Range; - hours: Range; - days: Range; - weeks: Range; - months: Range; - years: Range; - - sundays: Range; - mondays: Range; - tuesdays: Range; - wednesdays: Range; - thursdays: Range; - fridays: Range; - saturdays: Range; - format: { - /** - * Constructs a new local time formatter using the given specifier. - */ - (specifier: string): TimeFormat; - /** - * Returns a new multi-resolution time format given the specified array of predicated formats. - */ - multi: (formats: any[][]) => TimeFormat; - - utc: { - /** - * Constructs a new local time formatter using the given specifier. - */ - (specifier: string): TimeFormat; - /** - * Returns a new multi-resolution UTC time format given the specified array of predicated formats. - */ - multi: (formats: any[][]) => TimeFormat; - }; - - /** - * The full ISO 8601 UTC time format: "%Y-%m-%dT%H:%M:%S.%LZ". - */ - iso: TimeFormat; - }; - - scale: { - /** - * Constructs a new time scale with the default domain and range; - * the ticks and tick format are configured for local time. - */ - (): Scale.TimeScale; - /** - * Constructs a new time scale with the default domain and range; - * the ticks and tick format are configured for UTC time. - */ - utc(): Scale.TimeScale; - }; - } - - export interface Range { - (start: Date, end: Date, step?: number): Date[]; - } - - export interface Interval { - (date: Date): Date; - floor: (date: Date) => Date; - round: (date: Date) => Date; - ceil: (date: Date) => Date; - range: Range; - offset: (date: Date, step: number) => Date; - utc?: Interval; - } - - export interface TimeFormat { - (date: Date): string; - parse: (string: string) => Date; - } - } - - // Layout - export module Layout { - export interface Layout { - /** - * Creates a new Stack layout - */ - stack(): StackLayout; - /** - * Creates a new pie layout - */ - pie(): PieLayout; - /** - * Creates a new force layout - */ - force(): ForceLayout; - /** - * Creates a new tree layout - */ - tree(): TreeLayout; - bundle(): BundleLayout; - chord(): ChordLayout; - cluster(): ClusterLayout; - hierarchy(): HierarchyLayout; - histogram(): HistogramLayout; - pack(): PackLayout; - partition(): PartitionLayout; - treemap(): TreeMapLayout; - } - - export interface StackLayout { - (layers: T[], index?: number): T[]; - values(accessor?: (d: any) => any): StackLayout; - offset(offset: string): StackLayout; - x(accessor: (d: any, i: number) => any): StackLayout; - y(accessor: (d: any, i: number) => any): StackLayout; - out(setter: (d: any, y0: number, y: number) => void): StackLayout; - } - - export interface TreeLayout { - /** - * Gets or sets the sort order of sibling nodes for the layout using the specified comparator function - */ - sort: { - /** - * Gets the sort order function of sibling nodes for the layout - */ - (): (d1: any, d2: any) => number; - /** - * Sets the sort order of sibling nodes for the layout using the specified comparator function - */ - (comparator: (d1: any, d2: any) => number): TreeLayout; - }; - /** - * Gets or sets the specified children accessor function - */ - children: { - /** - * Gets the children accessor function - */ - (): (d: any) => any; - /** - * Sets the specified children accessor function - */ - (children: (d: any) => any): TreeLayout; - }; - /** - * Runs the tree layout - */ - nodes(root: GraphNode): GraphNode[]; - /** - * Given the specified array of nodes, such as those returned by nodes, returns an array of objects representing the links from parent to child for each node - */ - links(nodes: GraphNode[]): GraphLink[]; - /** - * If separation is specified, uses the specified function to compute separation between neighboring nodes. If separation is not specified, returns the current separation function - */ - separation: { - /** - * Gets the current separation function - */ - (): (a: GraphNode, b: GraphNode) => number; - /** - * Sets the specified function to compute separation between neighboring nodes - */ - (separation: (a: GraphNode, b: GraphNode) => number): TreeLayout; - }; - /** - * Gets or sets the available layout size - */ - size: { - /** - * Gets the available layout size - */ - (): number[]; - /** - * Sets the available layout size - */ - (size: number[]): TreeLayout; - }; - /** - * Gets or sets the available node size - */ - nodeSize: { - /** - * Gets the available node size - */ - (): number[]; - /** - * Sets the available node size - */ - (size: number[]): TreeLayout; - }; - } - - export interface PieLayout { - (values: any[], index?: number): ArcDescriptor[]; - value: { - (): (d: any, index: number) => number; - (accessor: (d: any, index: number) => number): PieLayout; - }; - sort: { - (): (d1: any, d2: any) => number; - (comparator: (d1: any, d2: any) => number): PieLayout; - }; - startAngle: { - (): number; - (angle: number): PieLayout; - (angle: () => number): PieLayout; - (angle: (d : any) => number): PieLayout; - (angle: (d : any, i: number) => number): PieLayout; - }; - endAngle: { - (): number; - (angle: number): PieLayout; - (angle: () => number): PieLayout; - (angle: (d : any) => number): PieLayout - (angle: (d : any, i: number) => number): PieLayout; - }; - padAngle: { - (): number; - (angle: number): PieLayout; - (angle: () => number): PieLayout; - (angle: (d : any) => number): PieLayout - (angle: (d : any, i: number) => number): PieLayout; - }; - } - - export interface ArcDescriptor { - value: any; - data: any; - startAngle: number; - endAngle: number; - index: number; - } - - export interface GraphNode { - id?: number; - index?: number; - name?: string; - px?: number; - py?: number; - size?: number; - weight?: number; - x?: number; - y?: number; - subindex?: number; - startAngle?: number; - endAngle?: number; - value?: number; - fixed?: boolean; - children?: GraphNode[]; - _children?: GraphNode[]; - parent?: GraphNode; - depth?: number; - } - - export interface GraphLink { - source: GraphNode; - target: GraphNode; - } - - export interface GraphNodeForce { - index?: number; - x?: number; - y?: number; - px?: number; - py?: number; - fixed?: boolean; - weight?: number; - } - - export interface GraphLinkForce { - source: GraphNodeForce; - target: GraphNodeForce; - } - - export interface ForceLayout { - (): ForceLayout; - size: { - (): number[]; - (mysize: number[]): ForceLayout; - }; - linkDistance: { - (): number; - (number:number): ForceLayout; - (accessor: (d: any, index: number) => number): ForceLayout; - }; - linkStrength: - { - (): number; - (number:number): ForceLayout; - (accessor: (d: any, index: number) => number): ForceLayout; - }; - friction: - { - (): number; - (number:number): ForceLayout; - (accessor: (d: any, index: number) => number): ForceLayout; - }; - alpha: { - (): number; - (number:number): ForceLayout; - (accessor: (d: any, index: number) => number): ForceLayout; - }; - charge: { - (): number; - (number:number): ForceLayout; - (accessor: (d: any, index: number) => number): ForceLayout; - }; - - theta: { - (): number; - (number:number): ForceLayout; - (accessor: (d: any, index: number) => number): ForceLayout; - }; - - gravity: { - (): number; - (number:number): ForceLayout; - (accessor: (d: any, index: number) => number): ForceLayout; - }; - - links: { - (): GraphLinkForce[]; - (arLinks: GraphLinkForce[]): ForceLayout; - - }; - nodes: - { - (): GraphNodeForce[]; - (arNodes: GraphNodeForce[]): ForceLayout; - - }; - start(): ForceLayout; - resume(): ForceLayout; - stop(): ForceLayout; - tick(): ForceLayout; - on(type: string, listener: (arg:any) => void ): ForceLayout; - drag(): ForceLayout; - } - - export interface BundleLayout{ - (links: GraphLink[]): GraphNode[][]; - } - - export interface ChordLayout { - matrix: { - (): number[][]; - (matrix: number[][]): ChordLayout; - } - padding: { - (): number; - (padding: number): ChordLayout; - } - sortGroups: { - (): (a: number, b: number) => number; - (comparator: (a: number, b: number) => number): ChordLayout; - } - sortSubgroups: { - (): (a: number, b: number) => number; - (comparator: (a: number, b: number) => number): ChordLayout; - } - sortChords: { - (): (a: number, b: number) => number; - (comparator: (a: number, b: number) => number): ChordLayout; - } - chords(): GraphLink[]; - groups(): ArcDescriptor[]; - } - - export interface ClusterLayout{ - sort: { - (): (a: GraphNode, b: GraphNode) => number; - (comparator: (a: GraphNode, b: GraphNode) => number): ClusterLayout; - } - children: { - (): (d: any, i?: number) => GraphNode[]; - (children: (d: any, i?: number) => GraphNode[]): ClusterLayout; - } - nodes(root: GraphNode): GraphNode[]; - links(nodes: GraphNode[]): GraphLink[]; - separation: { - (): (a: GraphNode, b: GraphNode) => number; - (separation: (a: GraphNode, b: GraphNode) => number): ClusterLayout; - } - size: { - (): number[]; - (size: number[]): ClusterLayout; - } - value: { - (): (node: GraphNode) => number; - (value: (node: GraphNode) => number): ClusterLayout; - } - } - - export interface HierarchyLayout { - sort: { - (): (a: GraphNode, b: GraphNode) => number; - (comparator: (a: GraphNode, b: GraphNode) => number): HierarchyLayout; - } - children: { - (): (d: any, i?: number) => GraphNode[]; - (children: (d: any, i?: number) => GraphNode[]): HierarchyLayout; - } - nodes(root: GraphNode): GraphNode[]; - links(nodes: GraphNode[]): GraphLink[]; - value: { - (): (node: GraphNode) => number; - (value: (node: GraphNode) => number): HierarchyLayout; - } - reValue(root: GraphNode): HierarchyLayout; - } - - export interface Bin extends Array { - x: number; - dx: number; - y: number; - } - - export interface HistogramLayout { - (values: any[], index?: number): Bin[]; - value: { - (): (value: any) => any; - (accessor: (value: any) => any): HistogramLayout - } - range: { - (): (value: any, index: number) => number[]; - (range: (value: any, index: number) => number[]): HistogramLayout; - (range: number[]): HistogramLayout; - } - bins: { - (): (range: any[], index: number) => number[]; - (bins: (range: any[], index: number) => number[]): HistogramLayout; - (bins: number): HistogramLayout; - (bins: number[]): HistogramLayout; - } - frequency: { - (): boolean; - (frequency: boolean): HistogramLayout; - } - } - - export interface PackLayout { - sort: { - (): (a: GraphNode, b: GraphNode) => number; - (comparator: (a: GraphNode, b: GraphNode) => number): PackLayout; - } - children: { - (): (d: any, i?: number) => GraphNode[]; - (children: (d: any, i?: number) => GraphNode[]): PackLayout; - } - nodes(root: GraphNode): GraphNode[]; - links(nodes: GraphNode[]): GraphLink[]; - value: { - (): (node: GraphNode) => number; - (value: (node: GraphNode) => number): PackLayout; - } - size: { - (): number[]; - (size: number[]): PackLayout; - } - padding: { - (): number; - (padding: number): PackLayout; - } - } - - export interface PartitionLayout { - sort: { - (): (a: GraphNode, b: GraphNode) => number; - (comparator: (a: GraphNode, b: GraphNode) => number): PackLayout; - } - children: { - (): (d: any, i?: number) => GraphNode[]; - (children: (d: any, i?: number) => GraphNode[]): PackLayout; - } - nodes(root: GraphNode): GraphNode[]; - links(nodes: GraphNode[]): GraphLink[]; - value: { - (): (node: GraphNode) => number; - (value: (node: GraphNode) => number): PackLayout; - } - size: { - (): number[]; - (size: number[]): PackLayout; - } - } - - export interface TreeMapLayout { - sort: { - (): (a: GraphNode, b: GraphNode) => number; - (comparator: (a: GraphNode, b: GraphNode) => number): TreeMapLayout; - } - children: { - (): (d: any, i?: number) => GraphNode[]; - (children: (d: any, i?: number) => GraphNode[]): TreeMapLayout; - } - nodes(root: GraphNode): GraphNode[]; - links(nodes: GraphNode[]): GraphLink[]; - value: { - (): (node: GraphNode) => number; - (value: (node: GraphNode) => number): TreeMapLayout; - } - size: { - (): number[]; - (size: number[]): TreeMapLayout; - } - padding: { - (): number; - (padding: number): TreeMapLayout; - } - round: { - (): boolean; - (round: boolean): TreeMapLayout; - } - sticky: { - (): boolean; - (sticky: boolean): TreeMapLayout; - } - mode: { - (): string; - (mode: string): TreeMapLayout; - } - } - } - - // Color - export module Color { - export interface Color { - /** - * increase lightness by some exponential factor (gamma) - */ - brighter(k?: number): Color; - /** - * decrease lightness by some exponential factor (gamma) - */ - darker(k?: number): Color; - /** - * convert the color to a string. - */ - toString(): string; - } - - export interface RGBColor extends Color{ - /** - * the red color channel. - */ - r: number; - /** - * the green color channel. - */ - g: number; - /** - * the blue color channel. - */ - b: number; - /** - * convert from RGB to HSL. - */ - hsl(): HSLColor; - } - - export interface HSLColor extends Color{ - /** - * hue - */ - h: number; - /** - * saturation - */ - s: number; - /** - * lightness - */ - l: number; - /** - * convert from HSL to RGB. - */ - rgb(): RGBColor; - } - - export interface LABColor extends Color{ - /** - * lightness - */ - l: number; - /** - * a-dimension - */ - a: number; - /** - * b-dimension - */ - b: number; - /** - * convert from LAB to RGB. - */ - rgb(): RGBColor; - } - - export interface HCLColor extends Color{ - /** - * hue - */ - h: number; - /** - * chroma - */ - c: number; - /** - * luminance - */ - l: number; - /** - * convert from HCL to RGB. - */ - rgb(): RGBColor; - } - } - - // SVG - export module Svg { - export interface Svg { - /** - * Create a new symbol generator - */ - symbol(): Symbol; - /** - * Create a new axis generator - */ - axis(): Axis; - /** - * Create a new arc generator - */ - arc(): Arc; - /** - * Create a new line generator - */ - line: { - (): Line; - radial(): LineRadial; - } - /** - * Create a new area generator - */ - area: { - (): Area; - radial(): AreaRadial; - } - /** - * Create a new brush generator - */ - brush(): Brush; - /** - * Create a new chord generator - */ - chord(): Chord; - /** - * Create a new diagonal generator - */ - diagonal: { - (): Diagonal; - radial(): Diagonal; - } - /** - * The array of supported symbol types. - */ - symbolTypes: string[]; - } - - export interface Symbol { - type: (symbolType: string | ((datum: any, index: number) => string)) => Symbol; - size: (size: number | ((datum: any, index: number) => number)) => Symbol; - (datum?: any, index?: number): string; - } - - export interface Brush { - /** - * Draws or redraws this brush into the specified selection of elements - */ - (selection: _Selection): void; - /** - * Gets or sets the x-scale associated with the brush - */ - x: { - /** - * Gets the x-scale associated with the brush - */ - (): D3.Scale.Scale; - /** - * Sets the x-scale associated with the brush - * - * @param accessor The new Scale - */ - (scale: D3.Scale.Scale): Brush; - }; - /** - * Gets or sets the x-scale associated with the brush - */ - y: { - /** - * Gets the x-scale associated with the brush - */ - (): D3.Scale.Scale; - /** - * Sets the x-scale associated with the brush - * - * @param accessor The new Scale - */ - (scale: D3.Scale.Scale): Brush; - }; - /** - * Gets or sets the current brush extent - */ - extent: { - /** - * Gets the current brush extent - */ - (): any[]; - /** - * Sets the current brush extent - */ - (values: any[]): Brush; - }; - /** - * Clears the extent, making the brush extent empty. - */ - clear(): Brush; - /** - * Returns true if and only if the brush extent is empty - */ - empty(): boolean; - /** - * Gets or sets the listener for the specified event type - */ - on: { - /** - * Gets the listener for the specified event type - */ - (type: string): (data: any, index: number) => any; - /** - * Sets the listener for the specified event type - */ - (type: string, listener: (data: any, index: number) => any, capture?: boolean): Brush; - }; - } - - export interface Axis { - (selection: _Selection): void; - (transition: Transition.Transition): void; - - scale: { - (): any; - (scale: any): Axis; - }; - - orient: { - (): string; - (orientation: string): Axis; - }; - - ticks: { - (): any[]; - (...arguments: any[]): Axis; - }; - - tickPadding: { - (): number; - (padding: number): Axis; - }; - - tickValues: { - (): any[]; - (values: any[]): Axis; - }; - tickSubdivide(count: number): Axis; - tickSize: { - (): number; - (inner: number, outer?: number): Axis; - } - innerTickSize: { - (): number; - (value: number): Axis; - } - outerTickSize: { - (): number; - (value: number): Axis; - } - tickFormat(formatter: (value: any, index?: number) => string): Axis; - nice(count?: number): Axis; - } - - export interface Arc { - /** - * Returns the path data string - * - * @param data Array of data elements - * @param index Optional index - */ - (data: any, index?: number): string; - innerRadius: { - (): (data: any, index?: number) => number; - (radius: number): Arc; - (radius: () => number): Arc; - (radius: (data: any) => number): Arc; - (radius: (data: any, index: number) => number): Arc; - }; - outerRadius: { - (): (data: any, index?: number) => number; - (radius: number): Arc; - (radius: () => number): Arc; - (radius: (data: any) => number): Arc; - (radius: (data: any, index: number) => number): Arc; - }; - startAngle: { - (): (data: any, index?: number) => number; - (angle: number): Arc; - (angle: () => number): Arc; - (angle: (data: any) => number): Arc; - (angle: (data: any, index: number) => number): Arc; - }; - endAngle: { - (): (data: any, index?: number) => number; - (angle: number): Arc; - (angle: () => number): Arc; - (angle: (data: any) => number): Arc; - (angle: (data: any, index: number) => number): Arc; - }; - centroid(data: any, index?: number): number[]; - } - - export interface Line { - /** - * Returns the path data string - * - * @param data Array of data elements - * @param index Optional index - */ - (data: any[], index?: number): string; - /** - * Get or set the x-coordinate accessor. - */ - x: { - /** - * Get the x-coordinate accessor. - */ - (): (data: any, index ?: number) => number; - /** - * Set the x-coordinate accessor. - * - * @param accessor The new accessor function - */ - (accessor: (data: any) => number): Line; - (accessor: (data: any, index: number) => number): Line; - /** - * Set the x-coordinate to a constant. - * - * @param cnst The new constant value. - */ - (cnst: number): Line; - }; - /** - * Get or set the y-coordinate accessor. - */ - y: { - /** - * Get the y-coordinate accessor. - */ - (): (data: any, index ?: number) => number; - /** - * Set the y-coordinate accessor. - * - * @param accessor The new accessor function - */ - (accessor: (data: any) => number): Line; - (accessor: (data: any, index: number) => number): Line; - /** - * Set the y-coordinate to a constant. - * - * @param cnst The new constant value. - */ - (cnst: number): Line; - }; - /** - * Get or set the interpolation mode. - */ - interpolate: { - /** - * Get the interpolation accessor. - */ - (): string; - /** - * Set the interpolation accessor. - * - * @param interpolate The interpolation mode - */ - (interpolate: string): Line; - }; - /** - * Get or set the cardinal spline tension. - */ - tension: { - /** - * Get the cardinal spline accessor. - */ - (): number; - /** - * Set the cardinal spline accessor. - * - * @param tension The Cardinal spline interpolation tension - */ - (tension: number): Line; - }; - /** - * Control whether the line is defined at a given point. - */ - defined: { - /** - * Get the accessor function that controls where the line is defined. - */ - (): (data: any, index?: number) => boolean; - /** - * Set the accessor function that controls where the area is defined. - * - * @param defined The new accessor function - */ - (defined: (data: any, index?: number) => boolean): Line; - }; - } - - export interface LineRadial { - /** - * Returns the path data string - * - * @param data Array of data elements - * @param index Optional index - */ - (data: any[], index?: number): string; - /** - * Get or set the x-coordinate accessor. - */ - x: { - /** - * Get the x-coordinate accessor. - */ - (): (data: any, index ?: number) => number; - /** - * Set the x-coordinate accessor. - * - * @param accessor The new accessor function - */ - (accessor: (data: any) => number): LineRadial; - (accessor: (data: any, index: number) => number): LineRadial; - - /** - * Set the x-coordinate to a constant. - * - * @param cnst The new constant value. - */ - (cnst: number): LineRadial; - }; - /** - * Get or set the y-coordinate accessor. - */ - y: { - /** - * Get the y-coordinate accessor. - */ - (): (data: any, index ?: number) => number; - /** - * Set the y-coordinate accessor. - * - * @param accessor The new accessor function - */ - (accessor: (data: any) => number): LineRadial; - (accessor: (data: any, index: number) => number): LineRadial; - /** - * Set the y-coordinate to a constant. - * - * @param cnst The new constant value. - */ - (cnst: number): LineRadial; - }; - /** - * Get or set the interpolation mode. - */ - interpolate: { - /** - * Get the interpolation accessor. - */ - (): string; - /** - * Set the interpolation accessor. - * - * @param interpolate The interpolation mode - */ - (interpolate: string): LineRadial; - }; - /** - * Get or set the cardinal spline tension. - */ - tension: { - /** - * Get the cardinal spline accessor. - */ - (): number; - /** - * Set the cardinal spline accessor. - * - * @param tension The Cardinal spline interpolation tension - */ - (tension: number): LineRadial; - }; - /** - * Control whether the line is defined at a given point. - */ - defined: { - /** - * Get the accessor function that controls where the line is defined. - */ - (): (data: any) => any; - /** - * Set the accessor function that controls where the area is defined. - * - * @param defined The new accessor function - */ - (defined: (data: any) => any): LineRadial; - }; - radius: { - (): (d: any, i?: number) => number; - (radius: number): LineRadial; - (radius: (d: any) => number): LineRadial; - (radius: (d: any, i: number) => number): LineRadial; - } - angle: { - (): (d: any, i?: any) => number; - (angle: number): LineRadial; - (angle: (d: any) => number): LineRadial; - (angle: (d: any, i: any) => number): LineRadial; - } - } - - export interface Area { - /** - * Generate a piecewise linear area, as in an area chart. - */ - (data: any[], index?: number): string; - /** - * Get or set the x-coordinate accessor. - */ - x: { - /** - * Get the x-coordinate accessor. - */ - (): (data: any, index ?: number) => number; - /** - * Set the x-coordinate accessor. - * - * @param accessor The new accessor function - */ - (accessor: (data: any) => number): Area; - (accessor: (data: any, index: number) => number): Area; - /** - * Set the x-coordinate to a constant. - * - * @param cnst The new constant value. - */ - (cnst: number): Area; - }; - /** - * Get or set the x0-coordinate (baseline) accessor. - */ - x0: { - /** - * Get the x0-coordinate (baseline) accessor. - */ - (): (data: any, index ?: number) => number; - /** - * Set the x0-coordinate (baseline) accessor. - * - * @param accessor The new accessor function - */ - (accessor: (data: any) => number): Area; - (accessor: (data: any, index: number) => number): Area; - /** - * Set the x0-coordinate (baseline) to a constant. - * - * @param cnst The new constant value. - */ - (cnst: number): Area; - }; - /** - * Get or set the x1-coordinate (topline) accessor. - */ - x1: { - /** - * Get the x1-coordinate (topline) accessor. - */ - (): (data: any, index ?: number) => number; - /** - * Set the x1-coordinate (topline) accessor. - * - * @param accessor The new accessor function - */ - (accessor: (data: any) => number): Area; - (accessor: (data: any, index: number) => number): Area; - /** - * Set the x1-coordinate (topline) to a constant. - * - * @param cnst The new constant value. - */ - (cnst: number): Area; - }; - /** - * Get or set the y-coordinate accessor. - */ - y: { - /** - * Get the y-coordinate accessor. - */ - (): (data: any, index ?: number) => number; - /** - * Set the y-coordinate accessor. - * - * @param accessor The new accessor function - */ - (accessor: (data: any) => number): Area; - (accessor: (data: any, index: number) => number): Area; - /** - * Set the y-coordinate to a constant. - * - * @param cnst The constant value - */ - (cnst: number): Area; - }; - /** - * Get or set the y0-coordinate (baseline) accessor. - */ - y0: { - /** - * Get the y0-coordinate (baseline) accessor. - */ - (): (data: any, index ?: number) => number; - /** - * Set the y0-coordinate (baseline) accessor. - * - * @param accessor The new accessor function - */ - (accessor: (data: any) => number): Area; - (accessor: (data: any, index: number) => number): Area; - /** - * Set the y0-coordinate (baseline) to a constant. - * - * @param cnst The constant value - */ - (cnst: number): Area; - }; - /** - * Get or set the y1-coordinate (topline) accessor. - */ - y1: { - /** - * Get the y1-coordinate (topline) accessor. - */ - (): (data: any, index ?: number) => number; - /** - * Set the y1-coordinate (topline) accessor. - * - * @param accessor The new accessor function - */ - (accessor: (data: any) => number): Area; - (accessor: (data: any, index: number) => number): Area; - /** - * Set the y1-coordinate (baseline) to a constant. - * - * @param cnst The constant value - */ - (cnst: number): Area; - }; - /** - * Get or set the interpolation mode. - */ - interpolate: { - /** - * Get the interpolation accessor. - */ - (): string; - /** - * Set the interpolation accessor. - * - * @param interpolate The interpolation mode - */ - (interpolate: string): Area; - }; - /** - * Get or set the cardinal spline tension. - */ - tension: { - /** - * Get the cardinal spline accessor. - */ - (): number; - /** - * Set the cardinal spline accessor. - * - * @param tension The Cardinal spline interpolation tension - */ - (tension: number): Area; - }; - /** - * Control whether the area is defined at a given point. - */ - defined: { - /** - * Get the accessor function that controls where the area is defined. - */ - (): (data: any, index?: number) => any; - /** - * Set the accessor function that controls where the area is defined. - * - * @param defined The new accessor function - */ - (defined: (data: any, index?: number) => any): Area; - }; - } - - export interface AreaRadial { - /** - * Generate a piecewise linear area, as in an area chart. - */ - (data: any[], index?: number): string; - /** - * Get or set the x-coordinate accessor. - */ - x: { - /** - * Get the x-coordinate accessor. - */ - (): (data: any, index ?: number) => number; - /** - * Set the x-coordinate accessor. - * - * @param accessor The new accessor function - */ - (accessor: (data: any) => number): AreaRadial; - (accessor: (data: any, index: number) => number): AreaRadial; - /** - * Set the x-coordinate to a constant. - * - * @param cnst The new constant value. - */ - (cnst: number): AreaRadial; - }; - /** - * Get or set the x0-coordinate (baseline) accessor. - */ - x0: { - /** - * Get the x0-coordinate (baseline) accessor. - */ - (): (data: any, index ?: number) => number; - /** - * Set the x0-coordinate (baseline) accessor. - * - * @param accessor The new accessor function - */ - (accessor: (data: any) => number): AreaRadial; - (accessor: (data: any, index: number) => number): AreaRadial; - /** - * Set the x0-coordinate to a constant. - * - * @param cnst The new constant value. - */ - (cnst: number): AreaRadial; - }; - /** - * Get or set the x1-coordinate (topline) accessor. - */ - x1: { - /** - * Get the x1-coordinate (topline) accessor. - */ - (): (data: any, index ?: number) => number; - /** - * Set the x1-coordinate (topline) accessor. - * - * @param accessor The new accessor function - */ - (accessor: (data: any) => number): AreaRadial; - (accessor: (data: any, index: number) => number): AreaRadial; - /** - * Set the x1-coordinate to a constant. - * - * @param cnst The new constant value. - */ - (cnst: number): AreaRadial; - }; - /** - * Get or set the y-coordinate accessor. - */ - y: { - /** - * Get the y-coordinate accessor. - */ - (): (data: any, index ?: number) => number; - /** - * Set the y-coordinate accessor. - * - * @param accessor The new accessor function - */ - (accessor: (data: any) => number): AreaRadial; - (accessor: (data: any, index: number) => number): AreaRadial; - /** - * Set the y-coordinate to a constant. - * - * @param cnst The new constant value. - */ - (cnst: number): AreaRadial; - }; - /** - * Get or set the y0-coordinate (baseline) accessor. - */ - y0: { - /** - * Get the y0-coordinate (baseline) accessor. - */ - (): (data: any, index ?: number) => number; - /** - * Set the y0-coordinate (baseline) accessor. - * - * @param accessor The new accessor function - */ - (accessor: (data: any) => number): AreaRadial; - (accessor: (data: any, index: number) => number): AreaRadial; - /** - * Set the y0-coordinate to a constant. - * - * @param cnst The new constant value. - */ - (cnst: number): AreaRadial; - }; - /** - * Get or set the y1-coordinate (topline) accessor. - */ - y1: { - /** - * Get the y1-coordinate (topline) accessor. - */ - (): (data: any, index ?: number) => number; - /** - * Set the y1-coordinate (topline) accessor. - * - * @param accessor The new accessor function - */ - (accessor: (data: any) => number): AreaRadial; - (accessor: (data: any, index: number) => number): AreaRadial; - /** - * Set the y1-coordinate to a constant. - * - * @param cnst The new constant value. - */ - (cnst: number): AreaRadial; - }; - /** - * Get or set the interpolation mode. - */ - interpolate: { - /** - * Get the interpolation accessor. - */ - (): string; - /** - * Set the interpolation accessor. - * - * @param interpolate The interpolation mode - */ - (interpolate: string): AreaRadial; - }; - /** - * Get or set the cardinal spline tension. - */ - tension: { - /** - * Get the cardinal spline accessor. - */ - (): number; - /** - * Set the cardinal spline accessor. - * - * @param tension The Cardinal spline interpolation tension - */ - (tension: number): AreaRadial; - }; - /** - * Control whether the area is defined at a given point. - */ - defined: { - /** - * Get the accessor function that controls where the area is defined. - */ - (): (data: any) => any; - /** - * Set the accessor function that controls where the area is defined. - * - * @param defined The new accessor function - */ - (defined: (data: any) => any): AreaRadial; - }; - radius: { - (): number; - (radius: number): AreaRadial; - (radius: () => number): AreaRadial; - (radius: (data: any) => number): AreaRadial; - (radius: (data: any, index: number) => number): AreaRadial; - }; - innerRadius: { - (): number; - (radius: number): AreaRadial; - (radius: () => number): AreaRadial; - (radius: (data: any) => number): AreaRadial; - (radius: (data: any, index: number) => number): AreaRadial; - }; - outerRadius: { - (): number; - (radius: number): AreaRadial; - (radius: () => number): AreaRadial; - (radius: (data: any) => number): AreaRadial; - (radius: (data: any, index: number) => number): AreaRadial; - }; - angle: { - (): number; - (angle: number): AreaRadial; - (angle: () => number): AreaRadial; - (angle: (data: any) => number): AreaRadial; - (angle: (data: any, index: number) => number): AreaRadial; - }; - startAngle: { - (): number; - (angle: number): AreaRadial; - (angle: () => number): AreaRadial; - (angle: (data: any) => number): AreaRadial; - (angle: (data: any, index: number) => number): AreaRadial; - }; - endAngle: { - (): number; - (angle: number): AreaRadial; - (angle: () => number): AreaRadial; - (angle: (data: any) => number): AreaRadial; - (angle: (data: any, index: number) => number): AreaRadial; - }; - } - - export interface Chord { - (datum: any, index?: number): string; - radius: { - (): number; - (radius: number): Chord; - (radius: () => number): Chord; - }; - startAngle: { - (): number; - (angle: number): Chord; - (angle: () => number): Chord; - }; - endAngle: { - (): number; - (angle: number): Chord; - (angle: () => number): Chord; - }; - source: { - (): any; - (angle: any): Chord; - (angle: (d: any, i?: number) => any): Chord; - }; - target: { - (): any; - (angle: any): Chord; - (angle: (d: any, i?: number) => any): Chord; - }; - } - - export interface Diagonal { - (datum: any, index?: number): string; - projection: { - (): (datum: any, index?: number) => number[]; - (proj: (datum: any) => number[]): Diagonal; - (proj: (datum: any, index: number) => number[]): Diagonal; - }; - source: { - (): (datum: any, index?: number) => any; - (src: (datum: any) => any): Diagonal; - (src: (datum: any, index: number) => any): Diagonal; - (src: any): Diagonal; - }; - target: { - (): (datum: any, index?: number) => any; - (target: (d: any) => any): Diagonal; - (target: (d: any, i: number) => any): Diagonal; - (target: any): Diagonal; - }; - } - } - - // Scales - export module Scale { - export interface ScaleBase { - /** - * Construct a linear quantitative scale. - */ - linear(): LinearScale; - /* - * Construct an ordinal scale. - */ - ordinal(): OrdinalScale; - /** - * Construct a linear quantitative scale with a discrete output range. - */ - quantize(): QuantizeScale; - /* - * Construct an ordinal scale with ten categorical colors. - */ - category10(): OrdinalScale; - /* - * Construct an ordinal scale with twenty categorical colors - */ - category20(): OrdinalScale; - /* - * Construct an ordinal scale with twenty categorical colors - */ - category20b(): OrdinalScale; - /* - * Construct an ordinal scale with twenty categorical colors - */ - category20c(): OrdinalScale; - /* - * Construct a linear identity scale. - */ - identity(): IdentityScale; - /* - * Construct a quantitative scale with an logarithmic transform. - */ - log(): LogScale; - /* - * Construct a quantitative scale with an exponential transform. - */ - pow(): PowScale; - /* - * Construct a quantitative scale mapping to quantiles. - */ - quantile(): QuantileScale; - /* - * Construct a quantitative scale with a square root transform. - */ - sqrt(): SqrtScale; - /* - * Construct a threshold scale with a discrete output range. - */ - threshold(): ThresholdScale; - } - - export interface GenericScale { - (value: any): any; - domain: { - (values: any[]): S; - (): any[]; - }; - range: { - (values: any[]): S; - (): any[]; - }; - invertExtent?(y: any): any[]; - copy(): S; - } - - export interface Scale extends GenericScale { } - - export interface GenericQuantitativeScale extends GenericScale { - /** - * Get the range value corresponding to a given domain value. - * - * @param value Domain Value - */ - (value: number): number; - /** - * Get the domain value corresponding to a given range value. - * - * @param value Range Value - */ - invert(value: number): number; - /** - * Set the scale's output range, and enable rounding. - * - * @param value The output range. - */ - rangeRound: (values: any[]) => S; - /** - * get or set the scale's output interpolator. - */ - interpolate: { - (): D3.Transition.Interpolate; - (factory: D3.Transition.Interpolate): S; - }; - /** - * enable or disable clamping of the output range. - * - * @param clamp Enable or disable - */ - clamp: { - (): boolean; - (clamp: boolean): S; - } - /** - * extend the scale domain to nice round numbers. - * - * @param count Optional number of ticks to exactly fit the domain - */ - nice(count?: number): S; - /** - * get representative values from the input domain. - * - * @param count Aproximate representative values to return. - */ - ticks(count: number): any[]; - /** - * get a formatter for displaying tick values - * - * @param count Aproximate representative values to return - */ - tickFormat(count: number, format?: string): (n: number) => string; - } - - export interface QuantitativeScale extends GenericQuantitativeScale { } - - export interface LinearScale extends GenericQuantitativeScale { } - - export interface IdentityScale extends GenericScale { - /** - * Get the range value corresponding to a given domain value. - * - * @param value Domain Value - */ - (value: number): number; - /** - * Get the domain value corresponding to a given range value. - * - * @param value Range Value - */ - invert(value: number): number; - /** - * get representative values from the input domain. - * - * @param count Aproximate representative values to return. - */ - ticks(count: number): any[]; - /** - * get a formatter for displaying tick values - * - * @param count Aproximate representative values to return - */ - tickFormat(count: number): (n: number) => string; - } - - export interface SqrtScale extends GenericQuantitativeScale { } - - export interface PowScale extends GenericQuantitativeScale { } - - export interface LogScale extends GenericQuantitativeScale { } - - export interface OrdinalScale extends GenericScale { - rangePoints(interval: any[], padding?: number): OrdinalScale; - rangeBands(interval: any[], padding?: number, outerPadding?: number): OrdinalScale; - rangeRoundBands(interval: any[], padding?: number, outerPadding?: number): OrdinalScale; - rangeBand(): number; - rangeExtent(): any[]; - } - - export interface QuantizeScale extends GenericScale { } - - export interface ThresholdScale extends GenericScale { } - - export interface QuantileScale extends GenericScale { - quantiles(): any[]; - } - - export interface TimeScale extends GenericScale { - (value: Date): number; - invert(value: number): Date; - rangeRound: (values: any[]) => TimeScale; - interpolate: { - (): D3.Transition.Interpolate; - (factory: D3.Transition.InterpolateFactory): TimeScale; - }; - clamp(clamp: boolean): TimeScale; - ticks: { - (count: number): any[]; - (range: D3.Time.Range, count: number): any[]; - }; - tickFormat(count: number): (n: number) => string; - nice(count?: number): TimeScale; - } - } - - // Behaviour - export module Behavior { - export interface Behavior{ - /** - * Constructs a new drag behaviour - */ - drag(): Drag; - /** - * Constructs a new zoom behaviour - */ - zoom(): Zoom; - } - - export interface Zoom { - /** - * Applies the zoom behavior to the specified selection, - * registering the necessary event listeners to support - * panning and zooming. - */ - (selection: _Selection): void; - - /** - * Registers a listener to receive events - * - * @param type Enent name to attach the listener to - * @param listener Function to attach to event - */ - on: (type: string, listener: (data: any, index?: number) => any) => Zoom; - - /** - * Gets or set the current zoom scale - */ - scale: { - /** - * Get the current current zoom scale - */ - (): number; - /** - * Set the current current zoom scale - * - * @param origin Zoom scale - */ - (scale: number): Zoom; - }; - - /** - * Gets or set the current zoom translation vector - */ - translate: { - /** - * Get the current zoom translation vector - */ - (): number[]; - /** - * Set the current zoom translation vector - * - * @param translate Tranlation vector - */ - (translate: number[]): Zoom; - }; - - /** - * Gets or set the allowed scale range - */ - scaleExtent: { - /** - * Get the current allowed zoom range - */ - (): number[]; - /** - * Set the allowable zoom range - * - * @param extent Allowed zoom range - */ - (extent: number[]): Zoom; - }; - - /** - * Gets or set the X-Scale that should be adjusted when zooming - */ - x: { - /** - * Get the X-Scale - */ - (): D3.Scale.Scale; - /** - * Set the X-Scale to be adjusted - * - * @param x The X Scale - */ - (x: D3.Scale.Scale): Zoom; - - }; - - /** - * Gets or set the Y-Scale that should be adjusted when zooming - */ - y: { - /** - * Get the Y-Scale - */ - (): D3.Scale.Scale; - /** - * Set the Y-Scale to be adjusted - * - * @param y The Y Scale - */ - (y: D3.Scale.Scale): Zoom; - }; - } - - export interface Drag { - /** - * Execute drag method - */ - (): any; - - /** - * Registers a listener to receive events - * - * @param type Enent name to attach the listener to - * @param listener Function to attach to event - */ - on: (type: string, listener: (data: any, index?: number) => any) => Drag; - - /** - * Gets or set the current origin accessor function - */ - origin: { - /** - * Get the current origin accessor function - */ - (): any; - /** - * Set the origin accessor function - * - * @param origin Accessor function - */ - (origin?: any): Drag; - }; - } - } - - // Geography - export module Geo { - export interface Geo { - /** - * create a new geographic path generator - */ - path(): Path; - /** - * create a circle generator. - */ - circle(): Circle; - /** - * compute the spherical area of a given feature. - */ - area(feature: any): number; - /** - * compute the latitude-longitude bounding box for a given feature. - */ - bounds(feature: any): number[][]; - /** - * compute the spherical centroid of a given feature. - */ - centroid(feature: any): number[]; - /** - * compute the great-arc distance between two points. - */ - distance(a: number[], b: number[]): number; - /** - * interpolate between two points along a great arc. - */ - interpolate(a: number[], b: number[]): (t: number) => number[]; - /** - * compute the length of a line string or the circumference of a polygon. - */ - length(feature: any): number; - /** - * create a standard projection from a raw projection. - */ - projection(raw: RawProjection): Projection; - /** - * create a standard projection from a mutable raw projection. - */ - projectionMutator(rawFactory: RawProjection): ProjectionMutator; - /** - * the Albers equal-area conic projection. - */ - albers(): Projection; - /** - * a composite Albers projection for the United States. - */ - albersUsa(): Projection; - /** - * the azimuthal equal-area projection. - */ - azimuthalEqualArea: { - (): Projection; - raw: RawProjection; - } - /** - * the azimuthal equidistant projection. - */ - azimuthalEquidistant: { - (): Projection; - raw: RawProjection; - } - /** - * the conic conformal projection. - */ - conicConformal: { - (): Projection; - raw(phi1:number, phi2:number): RawProjection; - } - /** - * the conic equidistant projection. - */ - conicEquidistant: { - (): Projection; - raw(phi1:number, phi2:number): RawProjection; - } - /** - * the conic equal-area (a.k.a. Albers) projection. - */ - conicEqualArea: { - (): Projection; - raw(phi1:number, phi2:number): RawProjection; - } - /** - * the equirectangular (plate carreé) projection. - */ - equirectangular: { - (): Projection; - raw: RawProjection; - } - /** - * the gnomonic projection. - */ - gnomonic: { - (): Projection; - raw: RawProjection; - } - /** - * the spherical Mercator projection. - */ - mercator: { - (): Projection; - raw: RawProjection; - } - /** - * the azimuthal orthographic projection. - */ - orthographic: { - (): Projection; - raw: RawProjection; - } - /** - * the azimuthal stereographic projection. - */ - stereographic: { - (): Projection; - raw: RawProjection; - } - /** - * the transverse Mercator projection. - */ - transverseMercator: { - (): Projection; - raw: RawProjection; - } - /** - * convert a GeoJSON object to a geometry stream. - */ - stream(object: GeoJSON, listener: Stream): void; - /** - * - */ - graticule(): Graticule; - /** - * - */ - greatArc(): GreatArc; - /** - * - */ - rotation(rotation: number[]): Rotation; - } - - export interface Path { - /** - * Returns the path data string for the given feature - */ - (feature: any, index?: any): string; - /** - * get or set the geographic projection. - */ - projection: { - /** - * get the geographic projection. - */ - (): Projection; - /** - * set the geographic projection. - */ - (projection: Projection): Path; - } - /** - * get or set the render context. - */ - context: { - /** - * return an SVG path string invoked on the given feature. - */ - (): string; - /** - * sets the render context and returns the path generator - */ - (context: Context): Path; - } - /** - * Computes the projected area - */ - area(feature: any): any; - /** - * Computes the projected centroid - */ - centroid(feature: any): any; - /** - * Computes the projected bounding box - */ - bounds(feature: any): any; - /** - * get or set the radius to display point features. - */ - pointRadius: { - /** - * returns the current radius - */ - (): number; - /** - * sets the radius used to display Point and MultiPoint features to the specified number - */ - (radius: number): Path; - /** - * sets the radius used to display Point and MultiPoint features to the specified number - */ - (radius: (feature: any, index: number) => number): Path; - } - } - - export interface Context { - beginPath(): any; - moveTo(x: number, y: number): any; - lineTo(x: number, y: number): any; - arc(x: number, y: number, radius: number, startAngle: number, endAngle: number): any; - closePath(): any; - } - - export interface Circle { - (...args: any[]): GeoJSON; - origin: { - (): number[]; - (origin: number[]): Circle; - (origin: (...args: any[]) => number[]): Circle; - } - angle: { - (): number; - (angle: number): Circle; - } - precision: { - (): number; - (precision: number): Circle; - } - } - - export interface Graticule{ - (): GeoJSON; - lines(): GeoJSON[]; - outline(): GeoJSON; - extent: { - (): number[][]; - (extent: number[][]): Graticule; - } - minorExtent: { - (): number[][]; - (extent: number[][]): Graticule; - } - majorExtent: { - (): number[][]; - (extent: number[][]): Graticule; - } - step: { - (): number[][]; - (extent: number[][]): Graticule; - } - minorStep: { - (): number[][]; - (extent: number[][]): Graticule; - } - majorStep: { - (): number[][]; - (extent: number[][]): Graticule; - } - precision: { - (): number; - (precision: number): Graticule; - } - } - - export interface GreatArc { - (): GeoJSON; - distance(): number; - source: { - (): any; - (source: any): GreatArc; - } - target: { - (): any; - (target: any): GreatArc; - } - precision: { - (): number; - (precision: number): GreatArc; - } - } - - export interface GeoJSON { - coordinates: number[][]; - type: string; - } - - export interface RawProjection { - (lambda: number, phi: number): number[]; - invert?(x: number, y: number): number[]; - } - - export interface Projection { - (coordinates: number[]): number[]; - invert?(point: number[]): number[]; - rotate: { - (): number[]; - (rotation: number[]): Projection; - }; - center: { - (): number[]; - (location: number[]): Projection; - }; - parallels: { - (): number[]; - (location: number[]): Projection; - }; - translate: { - (): number[]; - (point: number[]): Projection; - }; - scale: { - (): number; - (scale: number): Projection; - }; - clipAngle: { - (): number; - (angle: number): Projection; - }; - clipExtent: { - (): number[][]; - (extent: number[][]): Projection; - }; - precision: { - (): number; - (precision: number): Projection; - }; - stream(listener?: Stream): Stream; - } - - export interface Stream { - point(x: number, y: number, z?: number): void; - lineStart(): void; - lineEnd(): void; - polygonStart(): void; - polygonEnd(): void; - sphere(): void; - } - - export interface Rotation extends Array { - (location: number[]): Rotation; - invert(location: number[]): Rotation; - } - - export interface ProjectionMutator { - (lambda: number, phi: number): Projection; - } - } - - // Geometry - export module Geom { - export interface Geom { - voronoi(): Voronoi; - /** - * compute the Voronoi diagram for the specified points. - */ - voronoi(vertices: Vertice[]): Polygon[]; - /** - * compute the Delaunay triangulation for the specified points. - */ - delaunay(vertices?: Vertice[]): Polygon[]; - /** - * constructs a quadtree for an array of points. - */ - quadtree(): QuadtreeFactory; - /** - * Constructs a new quadtree for the specified array of points. - */ - quadtree(points: Point[], x1: number, y1: number, x2: number, y2: number): Quadtree; - /** - * Constructs a new quadtree for the specified array of points. - */ - quadtree(points: Point[], width: number, height: number): Quadtree; - /** - * Returns the input array of vertices with additional methods attached - */ - polygon(vertices:Vertice[]): Polygon; - /** - * creates a new hull layout with the default settings. - */ - hull(): Hull; - - hull(vertices:Vertice[]): Vertice[]; - } - - export interface Vertice extends Array { - /** - * Returns the angle of the vertice - */ - angle?: number; - } - - export interface Polygon extends Array { - /** - * Returns the signed area of this polygon - */ - area(): number; - /** - * Returns a two-element array representing the centroid of this polygon. - */ - centroid(): number[]; - /** - * Clips the subject polygon against this polygon - */ - clip(subject: Polygon): Polygon; - } - - export interface QuadtreeFactory { - /** - * Constructs a new quadtree for the specified array of points. - */ - (): Quadtree; - /** - * Constructs a new quadtree for the specified array of points. - */ - (points: Point[], x1: number, y1: number, x2: number, y2: number): Quadtree; - /** - * Constructs a new quadtree for the specified array of points. - */ - (points: Point[], width: number, height: number): Quadtree; - - x: { - (): (d: any) => any; - (accesor: (d: any) => any): QuadtreeFactory; - - } - y: { - (): (d: any) => any; - (accesor: (d: any) => any): QuadtreeFactory; - - } - size(): number[]; - size(size: number[]): QuadtreeFactory; - extent(): number[][]; - extent(points: number[][]): QuadtreeFactory; - } - - export interface Quadtree { - /** - * Adds a new point to the quadtree. - */ - add(point: Point): void; - visit(callback: any): void; - } - - export interface Point { - x: number; - y: number; - } - - export interface Voronoi { - /** - * Compute the Voronoi diagram for the specified data. - */ - (data: T[]): Polygon[]; - /** - * Compute the graph links for the Voronoi diagram for the specified data. - */ - links(data: T[]): Layout.GraphLink[]; - /** - * Compute the triangles for the Voronoi diagram for the specified data. - */ - triangles(data: T[]): number[][]; - x: { - /** - * Get the x-coordinate accessor. - */ - (): (data: T, index ?: number) => number; - - /** - * Set the x-coordinate accessor. - * - * @param accessor The new accessor function - */ - (accessor: (data: T, index: number) => number): Voronoi; - - /** - * Set the x-coordinate to a constant. - * - * @param constant The new constant value. - */ - (constant: number): Voronoi; - } - y: { - /** - * Get the y-coordinate accessor. - */ - (): (data: T, index ?: number) => number; - - /** - * Set the y-coordinate accessor. - * - * @param accessor The new accessor function - */ - (accessor: (data: T, index: number) => number): Voronoi; - - /** - * Set the y-coordinate to a constant. - * - * @param constant The new constant value. - */ - (constant: number): Voronoi; - } - clipExtent: { - /** - * Get the clip extent. - */ - (): number[][]; - /** - * Set the clip extent. - * - * @param extent The new clip extent. - */ - (extent: number[][]): Voronoi; - } - size: { - /** - * Get the size. - */ - (): number[]; - /** - * Set the size, equivalent to a clip extent starting from (0,0). - * - * @param size The new size. - */ - (size: number[]): Voronoi; - } - } - - export interface Hull { - (vertices: Vertice[]): Vertice[]; - x: { - (): (d: any) => any; - (accesor: (d: any) => any): any; - } - y: { - (): (d: any) => any; - (accesor: (d: any) => any): any; - } - } - } -} - -declare var d3: D3.Base; - -declare module "d3" { - export = d3; -} diff --git a/lib/typings/emissary/emissary.d.ts b/lib/typings/emissary/emissary.d.ts deleted file mode 100644 index cbc484a3d..000000000 --- a/lib/typings/emissary/emissary.d.ts +++ /dev/null @@ -1,61 +0,0 @@ -// Type definitions for emissary -// Project: https://github.com/atom/emissary -// Definitions by: vvakame -// Definitions: https://github.com/borisyankov/DefinitelyTyped - -/// - -declare module Emissary { - interface IEmitterStatic extends Mixto.IMixinStatic { - new ():IEmitter; - } - - interface IEmitter { - on(eventNames:string, handler:Function):any; // return value type are Signal - once(eventName:string, handler:Function):any; // return value type are Signal - signal(eventName:string):void; - behavior(eventName:string, initialValue:any):void; - emit(eventName:string, ...args:any[]):void; - off(eventNames:string, handler:Function):void; - pauseEvents(eventNames:string):void; - resumeEvents(eventNames:string):void; - incrementSubscriptionCount(eventName:string):number; - decrementSubscriptionCount(eventName:string):number; - getSubscriptionCount(eventName:string):number; - hasSubscriptions(eventName:string):boolean; - } - - interface ISubscriberStatic extends Mixto.IMixinStatic { - new ():ISubscriber; - } - - interface ISubscriber { - subscribeWith(eventEmitter:any, methodName:string, args:any):ISubscription; - - addSubscription(subscription:any):ISubscription; - - subscribe(eventEmitterOrSubscription:any, ...args:any[]):ISubscription; - - subscribeToCommand(eventEmitter:any, ...args:any[]):ISubscription; - - unsubscribe(object?:any):any; - } - - interface ISubscriptionStatic { - new (emitter: any, eventNames:string, handler:Function):ISubscription; - } - - interface ISubscription extends IEmitter { - cancelled:boolean; - - off():any; - } -} - -declare module "emissary" { - var Emitter:Emissary.IEmitterStatic; - var Subscriber:Emissary.ISubscriberStatic; - var Signal:Function; // TODO - var Behavior:Function; // TODO - var combine:Function; // TODO -} diff --git a/lib/typings/htmltojsx/htmltojsx.d.ts b/lib/typings/htmltojsx/htmltojsx.d.ts deleted file mode 100644 index 5f32304b8..000000000 --- a/lib/typings/htmltojsx/htmltojsx.d.ts +++ /dev/null @@ -1,17 +0,0 @@ -// Type definitions for htmltojsx -// Project: https://www.npmjs.com/package/htmltojsx -// Definitions by: Basarat Ali Syed -// Definitions: https://github.com/borisyankov/DefinitelyTyped - -declare module 'htmltojsx' { - class HTMLtoJSX { - constructor(options?: { - createClass?: boolean; - outputClassName?: string; - /** as a string e.g. ' ' or '\t' */ - indent?: string; - }); - convert(html: string): string; - } - export = HTMLtoJSX; -} diff --git a/lib/typings/jquery/jquery.d.ts b/lib/typings/jquery/jquery.d.ts deleted file mode 100644 index b82711120..000000000 --- a/lib/typings/jquery/jquery.d.ts +++ /dev/null @@ -1,3185 +0,0 @@ -// Type definitions for jQuery 1.10.x / 2.0.x -// Project: http://jquery.com/ -// Definitions by: Boris Yankov , Christian Hoffmeister , Steve Fenton , Diullei Gomes , Tass Iliopoulos , Jason Swearingen , Sean Hill , Guus Goossens , Kelly Summerlin , Basarat Ali Syed , Nicholas Wolverson , Derek Cicerone , Andrew Gaspar , James Harrison Fisher , Seikichi Kondo , Benjamin Jackman , Poul Sorensen , Josh Strobl , John Reilly , Dick van den Brink -// Definitions: https://github.com/borisyankov/DefinitelyTyped - -/* ***************************************************************************** -Copyright (c) Microsoft Corporation. All rights reserved. -Licensed under the Apache License, Version 2.0 (the "License"); you may not use -this file except in compliance with the License. You may obtain a copy of the -License at http://www.apache.org/licenses/LICENSE-2.0 - -THIS CODE IS PROVIDED *AS IS* BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY -KIND, EITHER EXPRESS OR IMPLIED, INCLUDING WITHOUT LIMITATION ANY IMPLIED -WARRANTIES OR CONDITIONS OF TITLE, FITNESS FOR A PARTICULAR PURPOSE, -MERCHANTABLITY OR NON-INFRINGEMENT. - -See the Apache Version 2.0 License for specific language governing permissions -and limitations under the License. -***************************************************************************** */ - - -/** - * Interface for the AJAX setting that will configure the AJAX request - */ -interface JQueryAjaxSettings { - /** - * The content type sent in the request header that tells the server what kind of response it will accept in return. If the accepts setting needs modification, it is recommended to do so once in the $.ajaxSetup() method. - */ - accepts?: any; - /** - * By default, all requests are sent asynchronously (i.e. this is set to true by default). If you need synchronous requests, set this option to false. Cross-domain requests and dataType: "jsonp" requests do not support synchronous operation. Note that synchronous requests may temporarily lock the browser, disabling any actions while the request is active. As of jQuery 1.8, the use of async: false with jqXHR ($.Deferred) is deprecated; you must use the success/error/complete callback options instead of the corresponding methods of the jqXHR object such as jqXHR.done() or the deprecated jqXHR.success(). - */ - async?: boolean; - /** - * A pre-request callback function that can be used to modify the jqXHR (in jQuery 1.4.x, XMLHTTPRequest) object before it is sent. Use this to set custom headers, etc. The jqXHR and settings objects are passed as arguments. This is an Ajax Event. Returning false in the beforeSend function will cancel the request. As of jQuery 1.5, the beforeSend option will be called regardless of the type of request. - */ - beforeSend? (jqXHR: JQueryXHR, settings: JQueryAjaxSettings): any; - /** - * If set to false, it will force requested pages not to be cached by the browser. Note: Setting cache to false will only work correctly with HEAD and GET requests. It works by appending "_={timestamp}" to the GET parameters. The parameter is not needed for other types of requests, except in IE8 when a POST is made to a URL that has already been requested by a GET. - */ - cache?: boolean; - /** - * A function to be called when the request finishes (after success and error callbacks are executed). The function gets passed two arguments: The jqXHR (in jQuery 1.4.x, XMLHTTPRequest) object and a string categorizing the status of the request ("success", "notmodified", "error", "timeout", "abort", or "parsererror"). As of jQuery 1.5, the complete setting can accept an array of functions. Each function will be called in turn. This is an Ajax Event. - */ - complete? (jqXHR: JQueryXHR, textStatus: string): any; - /** - * An object of string/regular-expression pairs that determine how jQuery will parse the response, given its content type. (version added: 1.5) - */ - contents?: { [key: string]: any; }; - //According to jQuery.ajax source code, ajax's option actually allows contentType to set to "false" - // https://github.com/borisyankov/DefinitelyTyped/issues/742 - /** - * When sending data to the server, use this content type. Default is "application/x-www-form-urlencoded; charset=UTF-8", which is fine for most cases. If you explicitly pass in a content-type to $.ajax(), then it is always sent to the server (even if no data is sent). The W3C XMLHttpRequest specification dictates that the charset is always UTF-8; specifying another charset will not force the browser to change the encoding. - */ - contentType?: any; - /** - * This object will be made the context of all Ajax-related callbacks. By default, the context is an object that represents the ajax settings used in the call ($.ajaxSettings merged with the settings passed to $.ajax). - */ - context?: any; - /** - * An object containing dataType-to-dataType converters. Each converter's value is a function that returns the transformed value of the response. (version added: 1.5) - */ - converters?: { [key: string]: any; }; - /** - * If you wish to force a crossDomain request (such as JSONP) on the same domain, set the value of crossDomain to true. This allows, for example, server-side redirection to another domain. (version added: 1.5) - */ - crossDomain?: boolean; - /** - * Data to be sent to the server. It is converted to a query string, if not already a string. It's appended to the url for GET-requests. See processData option to prevent this automatic processing. Object must be Key/Value pairs. If value is an Array, jQuery serializes multiple values with same key based on the value of the traditional setting (described below). - */ - data?: any; - /** - * A function to be used to handle the raw response data of XMLHttpRequest.This is a pre-filtering function to sanitize the response. You should return the sanitized data. The function accepts two arguments: The raw data returned from the server and the 'dataType' parameter. - */ - dataFilter? (data: any, ty: any): any; - /** - * The type of data that you're expecting back from the server. If none is specified, jQuery will try to infer it based on the MIME type of the response (an XML MIME type will yield XML, in 1.4 JSON will yield a JavaScript object, in 1.4 script will execute the script, and anything else will be returned as a string). - */ - dataType?: string; - /** - * A function to be called if the request fails. The function receives three arguments: The jqXHR (in jQuery 1.4.x, XMLHttpRequest) object, a string describing the type of error that occurred and an optional exception object, if one occurred. Possible values for the second argument (besides null) are "timeout", "error", "abort", and "parsererror". When an HTTP error occurs, errorThrown receives the textual portion of the HTTP status, such as "Not Found" or "Internal Server Error." As of jQuery 1.5, the error setting can accept an array of functions. Each function will be called in turn. Note: This handler is not called for cross-domain script and cross-domain JSONP requests. This is an Ajax Event. - */ - error? (jqXHR: JQueryXHR, textStatus: string, errorThrown: string): any; - /** - * Whether to trigger global Ajax event handlers for this request. The default is true. Set to false to prevent the global handlers like ajaxStart or ajaxStop from being triggered. This can be used to control various Ajax Events. - */ - global?: boolean; - /** - * An object of additional header key/value pairs to send along with requests using the XMLHttpRequest transport. The header X-Requested-With: XMLHttpRequest is always added, but its default XMLHttpRequest value can be changed here. Values in the headers setting can also be overwritten from within the beforeSend function. (version added: 1.5) - */ - headers?: { [key: string]: any; }; - /** - * Allow the request to be successful only if the response has changed since the last request. This is done by checking the Last-Modified header. Default value is false, ignoring the header. In jQuery 1.4 this technique also checks the 'etag' specified by the server to catch unmodified data. - */ - ifModified?: boolean; - /** - * Allow the current environment to be recognized as "local," (e.g. the filesystem), even if jQuery does not recognize it as such by default. The following protocols are currently recognized as local: file, *-extension, and widget. If the isLocal setting needs modification, it is recommended to do so once in the $.ajaxSetup() method. (version added: 1.5.1) - */ - isLocal?: boolean; - /** - * Override the callback function name in a jsonp request. This value will be used instead of 'callback' in the 'callback=?' part of the query string in the url. So {jsonp:'onJSONPLoad'} would result in 'onJSONPLoad=?' passed to the server. As of jQuery 1.5, setting the jsonp option to false prevents jQuery from adding the "?callback" string to the URL or attempting to use "=?" for transformation. In this case, you should also explicitly set the jsonpCallback setting. For example, { jsonp: false, jsonpCallback: "callbackName" } - */ - jsonp?: any; - /** - * Specify the callback function name for a JSONP request. This value will be used instead of the random name automatically generated by jQuery. It is preferable to let jQuery generate a unique name as it'll make it easier to manage the requests and provide callbacks and error handling. You may want to specify the callback when you want to enable better browser caching of GET requests. As of jQuery 1.5, you can also use a function for this setting, in which case the value of jsonpCallback is set to the return value of that function. - */ - jsonpCallback?: any; - /** - * A mime type to override the XHR mime type. (version added: 1.5.1) - */ - mimeType?: string; - /** - * A password to be used with XMLHttpRequest in response to an HTTP access authentication request. - */ - password?: string; - /** - * By default, data passed in to the data option as an object (technically, anything other than a string) will be processed and transformed into a query string, fitting to the default content-type "application/x-www-form-urlencoded". If you want to send a DOMDocument, or other non-processed data, set this option to false. - */ - processData?: boolean; - /** - * Only applies when the "script" transport is used (e.g., cross-domain requests with "jsonp" or "script" dataType and "GET" type). Sets the charset attribute on the script tag used in the request. Used when the character set on the local page is not the same as the one on the remote script. - */ - scriptCharset?: string; - /** - * An object of numeric HTTP codes and functions to be called when the response has the corresponding code. f the request is successful, the status code functions take the same parameters as the success callback; if it results in an error (including 3xx redirect), they take the same parameters as the error callback. (version added: 1.5) - */ - statusCode?: { [key: string]: any; }; - /** - * A function to be called if the request succeeds. The function gets passed three arguments: The data returned from the server, formatted according to the dataType parameter; a string describing the status; and the jqXHR (in jQuery 1.4.x, XMLHttpRequest) object. As of jQuery 1.5, the success setting can accept an array of functions. Each function will be called in turn. This is an Ajax Event. - */ - success? (data: any, textStatus: string, jqXHR: JQueryXHR): any; - /** - * Set a timeout (in milliseconds) for the request. This will override any global timeout set with $.ajaxSetup(). The timeout period starts at the point the $.ajax call is made; if several other requests are in progress and the browser has no connections available, it is possible for a request to time out before it can be sent. In jQuery 1.4.x and below, the XMLHttpRequest object will be in an invalid state if the request times out; accessing any object members may throw an exception. In Firefox 3.0+ only, script and JSONP requests cannot be cancelled by a timeout; the script will run even if it arrives after the timeout period. - */ - timeout?: number; - /** - * Set this to true if you wish to use the traditional style of param serialization. - */ - traditional?: boolean; - /** - * The type of request to make ("POST" or "GET"), default is "GET". Note: Other HTTP request methods, such as PUT and DELETE, can also be used here, but they are not supported by all browsers. - */ - type?: string; - /** - * A string containing the URL to which the request is sent. - */ - url?: string; - /** - * A username to be used with XMLHttpRequest in response to an HTTP access authentication request. - */ - username?: string; - /** - * Callback for creating the XMLHttpRequest object. Defaults to the ActiveXObject when available (IE), the XMLHttpRequest otherwise. Override to provide your own implementation for XMLHttpRequest or enhancements to the factory. - */ - xhr?: any; - /** - * An object of fieldName-fieldValue pairs to set on the native XHR object. For example, you can use it to set withCredentials to true for cross-domain requests if needed. In jQuery 1.5, the withCredentials property was not propagated to the native XHR and thus CORS requests requiring it would ignore this flag. For this reason, we recommend using jQuery 1.5.1+ should you require the use of it. (version added: 1.5.1) - */ - xhrFields?: { [key: string]: any; }; -} - -/** - * Interface for the jqXHR object - */ -interface JQueryXHR extends XMLHttpRequest, JQueryPromise { - /** - * The .overrideMimeType() method may be used in the beforeSend() callback function, for example, to modify the response content-type header. As of jQuery 1.5.1, the jqXHR object also contains the overrideMimeType() method (it was available in jQuery 1.4.x, as well, but was temporarily removed in jQuery 1.5). - */ - overrideMimeType(mimeType: string): any; - /** - * Cancel the request. - * - * @param statusText A string passed as the textStatus parameter for the done callback. Default value: "canceled" - */ - abort(statusText?: string): void; - /** - * Incorporates the functionality of the .done() and .fail() methods, allowing (as of jQuery 1.8) the underlying Promise to be manipulated. Refer to deferred.then() for implementation details. - */ - then(doneCallback: (data: any, textStatus: string, jqXHR: JQueryXHR) => void, failCallback?: (jqXHR: JQueryXHR, textStatus: string, errorThrown: any) => void): JQueryPromise; - /** - * Property containing the parsed response if the response Content-Type is json - */ - responseJSON?: any; -} - -/** - * Interface for the JQuery callback - */ -interface JQueryCallback { - /** - * Add a callback or a collection of callbacks to a callback list. - * - * @param callbacks A function, or array of functions, that are to be added to the callback list. - */ - add(callbacks: Function): JQueryCallback; - /** - * Add a callback or a collection of callbacks to a callback list. - * - * @param callbacks A function, or array of functions, that are to be added to the callback list. - */ - add(callbacks: Function[]): JQueryCallback; - - /** - * Disable a callback list from doing anything more. - */ - disable(): JQueryCallback; - - /** - * Determine if the callbacks list has been disabled. - */ - disabled(): boolean; - - /** - * Remove all of the callbacks from a list. - */ - empty(): JQueryCallback; - - /** - * Call all of the callbacks with the given arguments - * - * @param arguments The argument or list of arguments to pass back to the callback list. - */ - fire(...arguments: any[]): JQueryCallback; - - /** - * Determine if the callbacks have already been called at least once. - */ - fired(): boolean; - - /** - * Call all callbacks in a list with the given context and arguments. - * - * @param context A reference to the context in which the callbacks in the list should be fired. - * @param arguments An argument, or array of arguments, to pass to the callbacks in the list. - */ - fireWith(context?: any, ...args: any[]): JQueryCallback; - - /** - * Determine whether a supplied callback is in a list - * - * @param callback The callback to search for. - */ - has(callback: Function): boolean; - - /** - * Lock a callback list in its current state. - */ - lock(): JQueryCallback; - - /** - * Determine if the callbacks list has been locked. - */ - locked(): boolean; - - /** - * Remove a callback or a collection of callbacks from a callback list. - * - * @param callbacks A function, or array of functions, that are to be removed from the callback list. - */ - remove(callbacks: Function): JQueryCallback; - /** - * Remove a callback or a collection of callbacks from a callback list. - * - * @param callbacks A function, or array of functions, that are to be removed from the callback list. - */ - remove(callbacks: Function[]): JQueryCallback; -} - -/** - * Allows jQuery Promises to interop with non-jQuery promises - */ -interface JQueryGenericPromise { - /** - * Add handlers to be called when the Deferred object is resolved, rejected, or still in progress. - * - * @param doneFilter A function that is called when the Deferred is resolved. - * @param failFilter An optional function that is called when the Deferred is rejected. - */ - then(doneFilter: (value: T) => U|JQueryGenericPromise, failFilter?: (reason: any) => U|JQueryGenericPromise): JQueryGenericPromise; -} - -/** - * Interface for the JQuery promise/deferred callbacks - */ -interface JQueryPromiseCallback { - (value?: T, ...args: any[]): void; -} - -interface JQueryPromiseOperator { - (callback: JQueryPromiseCallback, ...callbacks: JQueryPromiseCallback[]): JQueryPromise; - (callback: JQueryPromiseCallback[], ...callbacks: JQueryPromiseCallback[]): JQueryPromise; -} - -/** - * Interface for the JQuery promise, part of callbacks - */ -interface JQueryPromise { - /** - * Add handlers to be called when the Deferred object is either resolved or rejected. - * - * @param alwaysCallbacks1 A function, or array of functions, that is called when the Deferred is resolved or rejected. - * @param alwaysCallbacks2 Optional additional functions, or arrays of functions, that are called when the Deferred is resolved or rejected. - */ - always: JQueryPromiseOperator; - /** - * Add handlers to be called when the Deferred object is resolved. - * - * @param doneCallbacks1 A function, or array of functions, that are called when the Deferred is resolved. - * @param doneCallbacks2 Optional additional functions, or arrays of functions, that are called when the Deferred is resolved. - */ - done: JQueryPromiseOperator; - /** - * Add handlers to be called when the Deferred object is rejected. - * - * @param failCallbacks1 A function, or array of functions, that are called when the Deferred is rejected. - * @param failCallbacks2 Optional additional functions, or arrays of functions, that are called when the Deferred is rejected. - */ - fail: JQueryPromiseOperator; - /** - * Add handlers to be called when the Deferred object generates progress notifications. - * - * @param progressCallbacks A function, or array of functions, to be called when the Deferred generates progress notifications. - */ - progress(progressCallback: JQueryPromiseCallback): JQueryPromise; - progress(progressCallbacks: JQueryPromiseCallback[]): JQueryPromise; - - /** - * Determine the current state of a Deferred object. - */ - state(): string; - - // Deprecated - given no typings - pipe(doneFilter?: (x: any) => any, failFilter?: (x: any) => any, progressFilter?: (x: any) => any): JQueryPromise; - - /** - * Add handlers to be called when the Deferred object is resolved, rejected, or still in progress. - * - * @param doneFilter A function that is called when the Deferred is resolved. - * @param failFilter An optional function that is called when the Deferred is rejected. - * @param progressFilter An optional function that is called when progress notifications are sent to the Deferred. - */ - then(doneFilter: (value: T) => U|JQueryGenericPromise, failFilter?: (...reasons: any[]) => U|JQueryGenericPromise, progressFilter?: (...progression: any[]) => any): JQueryPromise; - - // Because JQuery Promises Suck - /** - * Add handlers to be called when the Deferred object is resolved, rejected, or still in progress. - * - * @param doneFilter A function that is called when the Deferred is resolved. - * @param failFilter An optional function that is called when the Deferred is rejected. - * @param progressFilter An optional function that is called when progress notifications are sent to the Deferred. - */ - then(doneFilter: (...values: any[]) => U|JQueryGenericPromise, failFilter?: (...reasons: any[]) => U|JQueryGenericPromise, progressFilter?: (...progression: any[]) => any): JQueryPromise; -} - -/** - * Interface for the JQuery deferred, part of callbacks - */ -interface JQueryDeferred extends JQueryPromise { - /** - * Add handlers to be called when the Deferred object is either resolved or rejected. - * - * @param alwaysCallbacks1 A function, or array of functions, that is called when the Deferred is resolved or rejected. - * @param alwaysCallbacks2 Optional additional functions, or arrays of functions, that are called when the Deferred is resolved or rejected. - */ - always(alwaysCallbacks1?: JQueryPromiseCallback, ...alwaysCallbacks2: JQueryPromiseCallback[]): JQueryDeferred; - always(alwaysCallbacks1?: JQueryPromiseCallback[], ...alwaysCallbacks2: JQueryPromiseCallback[]): JQueryDeferred; - always(alwaysCallbacks1?: JQueryPromiseCallback, ...alwaysCallbacks2: any[]): JQueryDeferred; - always(alwaysCallbacks1?: JQueryPromiseCallback[], ...alwaysCallbacks2: any[]): JQueryDeferred; - /** - * Add handlers to be called when the Deferred object is resolved. - * - * @param doneCallbacks1 A function, or array of functions, that are called when the Deferred is resolved. - * @param doneCallbacks2 Optional additional functions, or arrays of functions, that are called when the Deferred is resolved. - */ - done(doneCallbacks1?: JQueryPromiseCallback, ...doneCallbacks2: JQueryPromiseCallback[]): JQueryDeferred; - done(doneCallbacks1?: JQueryPromiseCallback[], ...doneCallbacks2: JQueryPromiseCallback[]): JQueryDeferred; - done(doneCallbacks1?: JQueryPromiseCallback, ...doneCallbacks2: any[]): JQueryDeferred; - done(doneCallbacks1?: JQueryPromiseCallback[], ...doneCallbacks2: any[]): JQueryDeferred; - /** - * Add handlers to be called when the Deferred object is rejected. - * - * @param failCallbacks1 A function, or array of functions, that are called when the Deferred is rejected. - * @param failCallbacks2 Optional additional functions, or arrays of functions, that are called when the Deferred is rejected. - */ - fail(failCallbacks1?: JQueryPromiseCallback, ...failCallbacks2: JQueryPromiseCallback[]): JQueryDeferred; - fail(failCallbacks1?: JQueryPromiseCallback[], ...failCallbacks2: JQueryPromiseCallback[]): JQueryDeferred; - fail(failCallbacks1?: JQueryPromiseCallback, ...failCallbacks2: any[]): JQueryDeferred; - fail(failCallbacks1?: JQueryPromiseCallback[], ...failCallbacks2: any[]): JQueryDeferred; - /** - * Add handlers to be called when the Deferred object generates progress notifications. - * - * @param progressCallbacks A function, or array of functions, to be called when the Deferred generates progress notifications. - */ - progress(progressCallback: JQueryPromiseCallback): JQueryDeferred; - progress(progressCallbacks: JQueryPromiseCallback[]): JQueryDeferred; - - /** - * Call the progressCallbacks on a Deferred object with the given args. - * - * @param args Optional arguments that are passed to the progressCallbacks. - */ - notify(...args: any[]): JQueryDeferred; - - /** - * Call the progressCallbacks on a Deferred object with the given context and args. - * - * @param context Context passed to the progressCallbacks as the this object. - * @param args Optional arguments that are passed to the progressCallbacks. - */ - notifyWith(context: any, ...args: any[]): JQueryDeferred; - - /** - * Reject a Deferred object and call any failCallbacks with the given args. - * - * @param args Optional arguments that are passed to the failCallbacks. - */ - reject(...args: any[]): JQueryDeferred; - /** - * Reject a Deferred object and call any failCallbacks with the given context and args. - * - * @param context Context passed to the failCallbacks as the this object. - * @param args An optional array of arguments that are passed to the failCallbacks. - */ - rejectWith(context: any, ...args: any[]): JQueryDeferred; - - /** - * Resolve a Deferred object and call any doneCallbacks with the given args. - * - * @param value First argument passed to doneCallbacks. - * @param args Optional subsequent arguments that are passed to the doneCallbacks. - */ - resolve(value?: T, ...args: any[]): JQueryDeferred; - - /** - * Resolve a Deferred object and call any doneCallbacks with the given context and args. - * - * @param context Context passed to the doneCallbacks as the this object. - * @param args An optional array of arguments that are passed to the doneCallbacks. - */ - resolveWith(context: any, ...args: any[]): JQueryDeferred; - - /** - * Return a Deferred's Promise object. - * - * @param target Object onto which the promise methods have to be attached - */ - promise(target?: any): JQueryPromise; -} - -/** - * Interface of the JQuery extension of the W3C event object - */ -interface BaseJQueryEventObject extends Event { - data: any; - delegateTarget: Element; - isDefaultPrevented(): boolean; - isImmediatePropagationStopped(): boolean; - isPropagationStopped(): boolean; - namespace: string; - originalEvent: Event; - preventDefault(): any; - relatedTarget: Element; - result: any; - stopImmediatePropagation(): void; - stopPropagation(): void; - target: Element; - pageX: number; - pageY: number; - which: number; - metaKey: boolean; -} - -interface JQueryInputEventObject extends BaseJQueryEventObject { - altKey: boolean; - ctrlKey: boolean; - metaKey: boolean; - shiftKey: boolean; -} - -interface JQueryMouseEventObject extends JQueryInputEventObject { - button: number; - clientX: number; - clientY: number; - offsetX: number; - offsetY: number; - pageX: number; - pageY: number; - screenX: number; - screenY: number; -} - -interface JQueryKeyEventObject extends JQueryInputEventObject { - char: any; - charCode: number; - key: any; - keyCode: number; -} - -interface JQueryEventObject extends BaseJQueryEventObject, JQueryInputEventObject, JQueryMouseEventObject, JQueryKeyEventObject{ -} - -/* - Collection of properties of the current browser -*/ - -interface JQuerySupport { - ajax?: boolean; - boxModel?: boolean; - changeBubbles?: boolean; - checkClone?: boolean; - checkOn?: boolean; - cors?: boolean; - cssFloat?: boolean; - hrefNormalized?: boolean; - htmlSerialize?: boolean; - leadingWhitespace?: boolean; - noCloneChecked?: boolean; - noCloneEvent?: boolean; - opacity?: boolean; - optDisabled?: boolean; - optSelected?: boolean; - scriptEval? (): boolean; - style?: boolean; - submitBubbles?: boolean; - tbody?: boolean; -} - -interface JQueryParam { - /** - * Create a serialized representation of an array or object, suitable for use in a URL query string or Ajax request. - * - * @param obj An array or object to serialize. - */ - (obj: any): string; - - /** - * Create a serialized representation of an array or object, suitable for use in a URL query string or Ajax request. - * - * @param obj An array or object to serialize. - * @param traditional A Boolean indicating whether to perform a traditional "shallow" serialization. - */ - (obj: any, traditional: boolean): string; -} - -/** - * The interface used to construct jQuery events (with $.Event). It is - * defined separately instead of inline in JQueryStatic to allow - * overriding the construction function with specific strings - * returning specific event objects. - */ -interface JQueryEventConstructor { - (name: string, eventProperties?: any): JQueryEventObject; - new (name: string, eventProperties?: any): JQueryEventObject; -} - -/** - * The interface used to specify coordinates. - */ -interface JQueryCoordinates { - left: number; - top: number; -} - -/** - * Elements in the array returned by serializeArray() - */ -interface JQuerySerializeArrayElement { - name: string; - value: string; -} - -interface JQueryAnimationOptions { - /** - * A string or number determining how long the animation will run. - */ - duration?: any; - /** - * A string indicating which easing function to use for the transition. - */ - easing?: string; - /** - * A function to call once the animation is complete. - */ - complete?: Function; - /** - * A function to be called for each animated property of each animated element. This function provides an opportunity to modify the Tween object to change the value of the property before it is set. - */ - step?: (now: number, tween: any) => any; - /** - * A function to be called after each step of the animation, only once per animated element regardless of the number of animated properties. (version added: 1.8) - */ - progress?: (animation: JQueryPromise, progress: number, remainingMs: number) => any; - /** - * A function to call when the animation begins. (version added: 1.8) - */ - start?: (animation: JQueryPromise) => any; - /** - * A function to be called when the animation completes (its Promise object is resolved). (version added: 1.8) - */ - done?: (animation: JQueryPromise, jumpedToEnd: boolean) => any; - /** - * A function to be called when the animation fails to complete (its Promise object is rejected). (version added: 1.8) - */ - fail?: (animation: JQueryPromise, jumpedToEnd: boolean) => any; - /** - * A function to be called when the animation completes or stops without completing (its Promise object is either resolved or rejected). (version added: 1.8) - */ - always?: (animation: JQueryPromise, jumpedToEnd: boolean) => any; - /** - * A Boolean indicating whether to place the animation in the effects queue. If false, the animation will begin immediately. As of jQuery 1.7, the queue option can also accept a string, in which case the animation is added to the queue represented by that string. When a custom queue name is used the animation does not automatically start; you must call .dequeue("queuename") to start it. - */ - queue?: any; - /** - * A map of one or more of the CSS properties defined by the properties argument and their corresponding easing functions. (version added: 1.4) - */ - specialEasing?: Object; -} - -/** - * Static members of jQuery (those on $ and jQuery themselves) - */ -interface JQueryStatic { - - /** - * Perform an asynchronous HTTP (Ajax) request. - * - * @param settings A set of key/value pairs that configure the Ajax request. All settings are optional. A default can be set for any option with $.ajaxSetup(). - */ - ajax(settings: JQueryAjaxSettings): JQueryXHR; - /** - * Perform an asynchronous HTTP (Ajax) request. - * - * @param url A string containing the URL to which the request is sent. - * @param settings A set of key/value pairs that configure the Ajax request. All settings are optional. A default can be set for any option with $.ajaxSetup(). - */ - ajax(url: string, settings?: JQueryAjaxSettings): JQueryXHR; - - /** - * Handle custom Ajax options or modify existing options before each request is sent and before they are processed by $.ajax(). - * - * @param dataTypes An optional string containing one or more space-separated dataTypes - * @param handler A handler to set default values for future Ajax requests. - */ - ajaxPrefilter(dataTypes: string, handler: (opts: any, originalOpts: JQueryAjaxSettings, jqXHR: JQueryXHR) => any): void; - /** - * Handle custom Ajax options or modify existing options before each request is sent and before they are processed by $.ajax(). - * - * @param handler A handler to set default values for future Ajax requests. - */ - ajaxPrefilter(handler: (opts: any, originalOpts: JQueryAjaxSettings, jqXHR: JQueryXHR) => any): void; - - ajaxSettings: JQueryAjaxSettings; - - /** - * Set default values for future Ajax requests. Its use is not recommended. - * - * @param options A set of key/value pairs that configure the default Ajax request. All options are optional. - */ - ajaxSetup(options: JQueryAjaxSettings): void; - - /** - * Load data from the server using a HTTP GET request. - * - * @param url A string containing the URL to which the request is sent. - * @param success A callback function that is executed if the request succeeds. - * @param dataType The type of data expected from the server. Default: Intelligent Guess (xml, json, script, or html). - */ - get(url: string, success?: (data: any, textStatus: string, jqXHR: JQueryXHR) => any, dataType?: string): JQueryXHR; - /** - * Load data from the server using a HTTP GET request. - * - * @param url A string containing the URL to which the request is sent. - * @param data A plain object or string that is sent to the server with the request. - * @param success A callback function that is executed if the request succeeds. - * @param dataType The type of data expected from the server. Default: Intelligent Guess (xml, json, script, or html). - */ - get(url: string, data?: Object|string, success?: (data: any, textStatus: string, jqXHR: JQueryXHR) => any, dataType?: string): JQueryXHR; - /** - * Load JSON-encoded data from the server using a GET HTTP request. - * - * @param url A string containing the URL to which the request is sent. - * @param success A callback function that is executed if the request succeeds. - */ - getJSON(url: string, success?: (data: any, textStatus: string, jqXHR: JQueryXHR) => any): JQueryXHR; - /** - * Load JSON-encoded data from the server using a GET HTTP request. - * - * @param url A string containing the URL to which the request is sent. - * @param data A plain object or string that is sent to the server with the request. - * @param success A callback function that is executed if the request succeeds. - */ - getJSON(url: string, data?: Object|string, success?: (data: any, textStatus: string, jqXHR: JQueryXHR) => any): JQueryXHR; - /** - * Load a JavaScript file from the server using a GET HTTP request, then execute it. - * - * @param url A string containing the URL to which the request is sent. - * @param success A callback function that is executed if the request succeeds. - */ - getScript(url: string, success?: (script: string, textStatus: string, jqXHR: JQueryXHR) => any): JQueryXHR; - - /** - * Create a serialized representation of an array or object, suitable for use in a URL query string or Ajax request. - */ - param: JQueryParam; - - /** - * Load data from the server using a HTTP POST request. - * - * @param url A string containing the URL to which the request is sent. - * @param success A callback function that is executed if the request succeeds. Required if dataType is provided, but can be null in that case. - * @param dataType The type of data expected from the server. Default: Intelligent Guess (xml, json, script, text, html). - */ - post(url: string, success?: (data: any, textStatus: string, jqXHR: JQueryXHR) => any, dataType?: string): JQueryXHR; - /** - * Load data from the server using a HTTP POST request. - * - * @param url A string containing the URL to which the request is sent. - * @param data A plain object or string that is sent to the server with the request. - * @param success A callback function that is executed if the request succeeds. Required if dataType is provided, but can be null in that case. - * @param dataType The type of data expected from the server. Default: Intelligent Guess (xml, json, script, text, html). - */ - post(url: string, data?: Object|string, success?: (data: any, textStatus: string, jqXHR: JQueryXHR) => any, dataType?: string): JQueryXHR; - - /** - * A multi-purpose callbacks list object that provides a powerful way to manage callback lists. - * - * @param flags An optional list of space-separated flags that change how the callback list behaves. - */ - Callbacks(flags?: string): JQueryCallback; - - /** - * Holds or releases the execution of jQuery's ready event. - * - * @param hold Indicates whether the ready hold is being requested or released - */ - holdReady(hold: boolean): void; - - /** - * Accepts a string containing a CSS selector which is then used to match a set of elements. - * - * @param selector A string containing a selector expression - * @param context A DOM Element, Document, or jQuery to use as context - */ - (selector: string, context?: Element|JQuery): JQuery; - /** - * Accepts a string containing a CSS selector which is then used to match a set of elements. - * - * @param element A DOM element to wrap in a jQuery object. - */ - (element: Element): JQuery; - /** - * Accepts a string containing a CSS selector which is then used to match a set of elements. - * - * @param elementArray An array containing a set of DOM elements to wrap in a jQuery object. - */ - (elementArray: Element[]): JQuery; - /** - * Accepts a string containing a CSS selector which is then used to match a set of elements. - * - * @param object A plain object to wrap in a jQuery object. - */ - (object: {}): JQuery; - /** - * Accepts a string containing a CSS selector which is then used to match a set of elements. - * - * @param object An existing jQuery object to clone. - */ - (object: JQuery): JQuery; - /** - * Specify a function to execute when the DOM is fully loaded. - */ - (): JQuery; - - /** - * Creates DOM elements on the fly from the provided string of raw HTML. - * - * @param html A string of HTML to create on the fly. Note that this parses HTML, not XML. - * @param ownerDocument A document in which the new elements will be created. - */ - (html: string, ownerDocument?: Document): JQuery; - /** - * Creates DOM elements on the fly from the provided string of raw HTML. - * - * @param html A string defining a single, standalone, HTML element (e.g.
    or
    ). - * @param attributes An object of attributes, events, and methods to call on the newly-created element. - */ - (html: string, attributes: Object): JQuery; - - /** - * Binds a function to be executed when the DOM has finished loading. - * - * @param callback A function to execute after the DOM is ready. - */ - (callback: Function): JQuery; - - /** - * Relinquish jQuery's control of the $ variable. - * - * @param removeAll A Boolean indicating whether to remove all jQuery variables from the global scope (including jQuery itself). - */ - noConflict(removeAll?: boolean): Object; - - /** - * Provides a way to execute callback functions based on one or more objects, usually Deferred objects that represent asynchronous events. - * - * @param deferreds One or more Deferred objects, or plain JavaScript objects. - */ - when(...deferreds: JQueryGenericPromise[]): JQueryPromise; - /** - * Provides a way to execute callback functions based on one or more objects, usually Deferred objects that represent asynchronous events. - * - * @param deferreds One or more Deferred objects, or plain JavaScript objects. - */ - when(...deferreds: T[]): JQueryPromise; - /** - * Provides a way to execute callback functions based on one or more objects, usually Deferred objects that represent asynchronous events. - * - * @param deferreds One or more Deferred objects, or plain JavaScript objects. - */ - when(...deferreds: any[]): JQueryPromise; - - /** - * Hook directly into jQuery to override how particular CSS properties are retrieved or set, normalize CSS property naming, or create custom properties. - */ - cssHooks: { [key: string]: any; }; - cssNumber: any; - - /** - * Store arbitrary data associated with the specified element. Returns the value that was set. - * - * @param element The DOM element to associate with the data. - * @param key A string naming the piece of data to set. - * @param value The new data value. - */ - data(element: Element, key: string, value: T): T; - /** - * Returns value at named data store for the element, as set by jQuery.data(element, name, value), or the full data store for the element. - * - * @param element The DOM element to associate with the data. - * @param key A string naming the piece of data to set. - */ - data(element: Element, key: string): any; - /** - * Returns value at named data store for the element, as set by jQuery.data(element, name, value), or the full data store for the element. - * - * @param element The DOM element to associate with the data. - */ - data(element: Element): any; - - /** - * Execute the next function on the queue for the matched element. - * - * @param element A DOM element from which to remove and execute a queued function. - * @param queueName A string containing the name of the queue. Defaults to fx, the standard effects queue. - */ - dequeue(element: Element, queueName?: string): void; - - /** - * Determine whether an element has any jQuery data associated with it. - * - * @param element A DOM element to be checked for data. - */ - hasData(element: Element): boolean; - - /** - * Show the queue of functions to be executed on the matched element. - * - * @param element A DOM element to inspect for an attached queue. - * @param queueName A string containing the name of the queue. Defaults to fx, the standard effects queue. - */ - queue(element: Element, queueName?: string): any[]; - /** - * Manipulate the queue of functions to be executed on the matched element. - * - * @param element A DOM element where the array of queued functions is attached. - * @param queueName A string containing the name of the queue. Defaults to fx, the standard effects queue. - * @param newQueue An array of functions to replace the current queue contents. - */ - queue(element: Element, queueName: string, newQueue: Function[]): JQuery; - /** - * Manipulate the queue of functions to be executed on the matched element. - * - * @param element A DOM element on which to add a queued function. - * @param queueName A string containing the name of the queue. Defaults to fx, the standard effects queue. - * @param callback The new function to add to the queue. - */ - queue(element: Element, queueName: string, callback: Function): JQuery; - - /** - * Remove a previously-stored piece of data. - * - * @param element A DOM element from which to remove data. - * @param name A string naming the piece of data to remove. - */ - removeData(element: Element, name?: string): JQuery; - - /** - * A constructor function that returns a chainable utility object with methods to register multiple callbacks into callback queues, invoke callback queues, and relay the success or failure state of any synchronous or asynchronous function. - * - * @param beforeStart A function that is called just before the constructor returns. - */ - Deferred(beforeStart?: (deferred: JQueryDeferred) => any): JQueryDeferred; - - /** - * Effects - */ - fx: { - tick: () => void; - /** - * The rate (in milliseconds) at which animations fire. - */ - interval: number; - stop: () => void; - speeds: { slow: number; fast: number; }; - /** - * Globally disable all animations. - */ - off: boolean; - step: any; - }; - - /** - * Takes a function and returns a new one that will always have a particular context. - * - * @param fnction The function whose context will be changed. - * @param context The object to which the context (this) of the function should be set. - * @param additionalArguments Any number of arguments to be passed to the function referenced in the function argument. - */ - proxy(fnction: (...args: any[]) => any, context: Object, ...additionalArguments: any[]): any; - /** - * Takes a function and returns a new one that will always have a particular context. - * - * @param context The object to which the context (this) of the function should be set. - * @param name The name of the function whose context will be changed (should be a property of the context object). - * @param additionalArguments Any number of arguments to be passed to the function named in the name argument. - */ - proxy(context: Object, name: string, ...additionalArguments: any[]): any; - - Event: JQueryEventConstructor; - - /** - * Takes a string and throws an exception containing it. - * - * @param message The message to send out. - */ - error(message: any): JQuery; - - expr: any; - fn: any; //TODO: Decide how we want to type this - - isReady: boolean; - - // Properties - support: JQuerySupport; - - /** - * Check to see if a DOM element is a descendant of another DOM element. - * - * @param container The DOM element that may contain the other element. - * @param contained The DOM element that may be contained by (a descendant of) the other element. - */ - contains(container: Element, contained: Element): boolean; - - /** - * A generic iterator function, which can be used to seamlessly iterate over both objects and arrays. Arrays and array-like objects with a length property (such as a function's arguments object) are iterated by numeric index, from 0 to length-1. Other objects are iterated via their named properties. - * - * @param collection The object or array to iterate over. - * @param callback The function that will be executed on every object. - */ - each( - collection: T[], - callback: (indexInArray: number, valueOfElement: T) => any - ): any; - - /** - * A generic iterator function, which can be used to seamlessly iterate over both objects and arrays. Arrays and array-like objects with a length property (such as a function's arguments object) are iterated by numeric index, from 0 to length-1. Other objects are iterated via their named properties. - * - * @param collection The object or array to iterate over. - * @param callback The function that will be executed on every object. - */ - each( - collection: any, - callback: (indexInArray: any, valueOfElement: any) => any - ): any; - - /** - * Merge the contents of two or more objects together into the first object. - * - * @param target An object that will receive the new properties if additional objects are passed in or that will extend the jQuery namespace if it is the sole argument. - * @param object1 An object containing additional properties to merge in. - * @param objectN Additional objects containing properties to merge in. - */ - extend(target: any, object1?: any, ...objectN: any[]): any; - /** - * Merge the contents of two or more objects together into the first object. - * - * @param deep If true, the merge becomes recursive (aka. deep copy). - * @param target The object to extend. It will receive the new properties. - * @param object1 An object containing additional properties to merge in. - * @param objectN Additional objects containing properties to merge in. - */ - extend(deep: boolean, target: any, object1?: any, ...objectN: any[]): any; - - /** - * Execute some JavaScript code globally. - * - * @param code The JavaScript code to execute. - */ - globalEval(code: string): any; - - /** - * Finds the elements of an array which satisfy a filter function. The original array is not affected. - * - * @param array The array to search through. - * @param func The function to process each item against. The first argument to the function is the item, and the second argument is the index. The function should return a Boolean value. this will be the global window object. - * @param invert If "invert" is false, or not provided, then the function returns an array consisting of all elements for which "callback" returns true. If "invert" is true, then the function returns an array consisting of all elements for which "callback" returns false. - */ - grep(array: T[], func: (elementOfArray: T, indexInArray: number) => boolean, invert?: boolean): T[]; - - /** - * Search for a specified value within an array and return its index (or -1 if not found). - * - * @param value The value to search for. - * @param array An array through which to search. - * @param fromIndex he index of the array at which to begin the search. The default is 0, which will search the whole array. - */ - inArray(value: T, array: T[], fromIndex?: number): number; - - /** - * Determine whether the argument is an array. - * - * @param obj Object to test whether or not it is an array. - */ - isArray(obj: any): boolean; - /** - * Check to see if an object is empty (contains no enumerable properties). - * - * @param obj The object that will be checked to see if it's empty. - */ - isEmptyObject(obj: any): boolean; - /** - * Determine if the argument passed is a Javascript function object. - * - * @param obj Object to test whether or not it is a function. - */ - isFunction(obj: any): boolean; - /** - * Determines whether its argument is a number. - * - * @param obj The value to be tested. - */ - isNumeric(value: any): boolean; - /** - * Check to see if an object is a plain object (created using "{}" or "new Object"). - * - * @param obj The object that will be checked to see if it's a plain object. - */ - isPlainObject(obj: any): boolean; - /** - * Determine whether the argument is a window. - * - * @param obj Object to test whether or not it is a window. - */ - isWindow(obj: any): boolean; - /** - * Check to see if a DOM node is within an XML document (or is an XML document). - * - * @param node he DOM node that will be checked to see if it's in an XML document. - */ - isXMLDoc(node: Node): boolean; - - /** - * Convert an array-like object into a true JavaScript array. - * - * @param obj Any object to turn into a native Array. - */ - makeArray(obj: any): any[]; - - /** - * Translate all items in an array or object to new array of items. - * - * @param array The Array to translate. - * @param callback The function to process each item against. The first argument to the function is the array item, the second argument is the index in array The function can return any value. Within the function, this refers to the global (window) object. - */ - map(array: T[], callback: (elementOfArray: T, indexInArray: number) => U): U[]; - /** - * Translate all items in an array or object to new array of items. - * - * @param arrayOrObject The Array or Object to translate. - * @param callback The function to process each item against. The first argument to the function is the value; the second argument is the index or key of the array or object property. The function can return any value to add to the array. A returned array will be flattened into the resulting array. Within the function, this refers to the global (window) object. - */ - map(arrayOrObject: any, callback: (value: any, indexOrKey: any) => any): any; - - /** - * Merge the contents of two arrays together into the first array. - * - * @param first The first array to merge, the elements of second added. - * @param second The second array to merge into the first, unaltered. - */ - merge(first: T[], second: T[]): T[]; - - /** - * An empty function. - */ - noop(): any; - - /** - * Return a number representing the current time. - */ - now(): number; - - /** - * Takes a well-formed JSON string and returns the resulting JavaScript object. - * - * @param json The JSON string to parse. - */ - parseJSON(json: string): any; - - /** - * Parses a string into an XML document. - * - * @param data a well-formed XML string to be parsed - */ - parseXML(data: string): XMLDocument; - - /** - * Remove the whitespace from the beginning and end of a string. - * - * @param str Remove the whitespace from the beginning and end of a string. - */ - trim(str: string): string; - - /** - * Determine the internal JavaScript [[Class]] of an object. - * - * @param obj Object to get the internal JavaScript [[Class]] of. - */ - type(obj: any): string; - - /** - * Sorts an array of DOM elements, in place, with the duplicates removed. Note that this only works on arrays of DOM elements, not strings or numbers. - * - * @param array The Array of DOM elements. - */ - unique(array: Element[]): Element[]; - - /** - * Parses a string into an array of DOM nodes. - * - * @param data HTML string to be parsed - * @param context DOM element to serve as the context in which the HTML fragment will be created - * @param keepScripts A Boolean indicating whether to include scripts passed in the HTML string - */ - parseHTML(data: string, context?: HTMLElement, keepScripts?: boolean): any[]; - - /** - * Parses a string into an array of DOM nodes. - * - * @param data HTML string to be parsed - * @param context DOM element to serve as the context in which the HTML fragment will be created - * @param keepScripts A Boolean indicating whether to include scripts passed in the HTML string - */ - parseHTML(data: string, context?: Document, keepScripts?: boolean): any[]; -} - -/** - * The jQuery instance members - */ -interface JQuery { - /** - * Register a handler to be called when Ajax requests complete. This is an AjaxEvent. - * - * @param handler The function to be invoked. - */ - ajaxComplete(handler: (event: JQueryEventObject, XMLHttpRequest: XMLHttpRequest, ajaxOptions: any) => any): JQuery; - /** - * Register a handler to be called when Ajax requests complete with an error. This is an Ajax Event. - * - * @param handler The function to be invoked. - */ - ajaxError(handler: (event: JQueryEventObject, jqXHR: JQueryXHR, ajaxSettings: JQueryAjaxSettings, thrownError: any) => any): JQuery; - /** - * Attach a function to be executed before an Ajax request is sent. This is an Ajax Event. - * - * @param handler The function to be invoked. - */ - ajaxSend(handler: (event: JQueryEventObject, jqXHR: JQueryXHR, ajaxOptions: JQueryAjaxSettings) => any): JQuery; - /** - * Register a handler to be called when the first Ajax request begins. This is an Ajax Event. - * - * @param handler The function to be invoked. - */ - ajaxStart(handler: () => any): JQuery; - /** - * Register a handler to be called when all Ajax requests have completed. This is an Ajax Event. - * - * @param handler The function to be invoked. - */ - ajaxStop(handler: () => any): JQuery; - /** - * Attach a function to be executed whenever an Ajax request completes successfully. This is an Ajax Event. - * - * @param handler The function to be invoked. - */ - ajaxSuccess(handler: (event: JQueryEventObject, XMLHttpRequest: XMLHttpRequest, ajaxOptions: JQueryAjaxSettings) => any): JQuery; - - /** - * Load data from the server and place the returned HTML into the matched element. - * - * @param url A string containing the URL to which the request is sent. - * @param data A plain object or string that is sent to the server with the request. - * @param complete A callback function that is executed when the request completes. - */ - load(url: string, data?: string|Object, complete?: (responseText: string, textStatus: string, XMLHttpRequest: XMLHttpRequest) => any): JQuery; - - /** - * Encode a set of form elements as a string for submission. - */ - serialize(): string; - /** - * Encode a set of form elements as an array of names and values. - */ - serializeArray(): JQuerySerializeArrayElement[]; - - /** - * Adds the specified class(es) to each of the set of matched elements. - * - * @param className One or more space-separated classes to be added to the class attribute of each matched element. - */ - addClass(className: string): JQuery; - /** - * Adds the specified class(es) to each of the set of matched elements. - * - * @param function A function returning one or more space-separated class names to be added to the existing class name(s). Receives the index position of the element in the set and the existing class name(s) as arguments. Within the function, this refers to the current element in the set. - */ - addClass(func: (index: number, className: string) => string): JQuery; - - /** - * Add the previous set of elements on the stack to the current set, optionally filtered by a selector. - */ - addBack(selector?: string): JQuery; - - /** - * Get the value of an attribute for the first element in the set of matched elements. - * - * @param attributeName The name of the attribute to get. - */ - attr(attributeName: string): string; - /** - * Set one or more attributes for the set of matched elements. - * - * @param attributeName The name of the attribute to set. - * @param value A value to set for the attribute. - */ - attr(attributeName: string, value: string|number): JQuery; - /** - * Set one or more attributes for the set of matched elements. - * - * @param attributeName The name of the attribute to set. - * @param func A function returning the value to set. this is the current element. Receives the index position of the element in the set and the old attribute value as arguments. - */ - attr(attributeName: string, func: (index: number, attr: string) => string|number): JQuery; - /** - * Set one or more attributes for the set of matched elements. - * - * @param attributes An object of attribute-value pairs to set. - */ - attr(attributes: Object): JQuery; - - /** - * Determine whether any of the matched elements are assigned the given class. - * - * @param className The class name to search for. - */ - hasClass(className: string): boolean; - - /** - * Get the HTML contents of the first element in the set of matched elements. - */ - html(): string; - /** - * Set the HTML contents of each element in the set of matched elements. - * - * @param htmlString A string of HTML to set as the content of each matched element. - */ - html(htmlString: string): JQuery; - /** - * Set the HTML contents of each element in the set of matched elements. - * - * @param func A function returning the HTML content to set. Receives the index position of the element in the set and the old HTML value as arguments. jQuery empties the element before calling the function; use the oldhtml argument to reference the previous content. Within the function, this refers to the current element in the set. - */ - html(func: (index: number, oldhtml: string) => string): JQuery; - /** - * Set the HTML contents of each element in the set of matched elements. - * - * @param func A function returning the HTML content to set. Receives the index position of the element in the set and the old HTML value as arguments. jQuery empties the element before calling the function; use the oldhtml argument to reference the previous content. Within the function, this refers to the current element in the set. - */ - - /** - * Get the value of a property for the first element in the set of matched elements. - * - * @param propertyName The name of the property to get. - */ - prop(propertyName: string): any; - /** - * Set one or more properties for the set of matched elements. - * - * @param propertyName The name of the property to set. - * @param value A value to set for the property. - */ - prop(propertyName: string, value: string|number|boolean): JQuery; - /** - * Set one or more properties for the set of matched elements. - * - * @param properties An object of property-value pairs to set. - */ - prop(properties: Object): JQuery; - /** - * Set one or more properties for the set of matched elements. - * - * @param propertyName The name of the property to set. - * @param func A function returning the value to set. Receives the index position of the element in the set and the old property value as arguments. Within the function, the keyword this refers to the current element. - */ - prop(propertyName: string, func: (index: number, oldPropertyValue: any) => any): JQuery; - - /** - * Remove an attribute from each element in the set of matched elements. - * - * @param attributeName An attribute to remove; as of version 1.7, it can be a space-separated list of attributes. - */ - removeAttr(attributeName: string): JQuery; - - /** - * Remove a single class, multiple classes, or all classes from each element in the set of matched elements. - * - * @param className One or more space-separated classes to be removed from the class attribute of each matched element. - */ - removeClass(className?: string): JQuery; - /** - * Remove a single class, multiple classes, or all classes from each element in the set of matched elements. - * - * @param function A function returning one or more space-separated class names to be removed. Receives the index position of the element in the set and the old class value as arguments. - */ - removeClass(func: (index: number, className: string) => string): JQuery; - - /** - * Remove a property for the set of matched elements. - * - * @param propertyName The name of the property to remove. - */ - removeProp(propertyName: string): JQuery; - - /** - * Add or remove one or more classes from each element in the set of matched elements, depending on either the class's presence or the value of the switch argument. - * - * @param className One or more class names (separated by spaces) to be toggled for each element in the matched set. - * @param swtch A Boolean (not just truthy/falsy) value to determine whether the class should be added or removed. - */ - toggleClass(className: string, swtch?: boolean): JQuery; - /** - * Add or remove one or more classes from each element in the set of matched elements, depending on either the class's presence or the value of the switch argument. - * - * @param swtch A boolean value to determine whether the class should be added or removed. - */ - toggleClass(swtch?: boolean): JQuery; - /** - * Add or remove one or more classes from each element in the set of matched elements, depending on either the class's presence or the value of the switch argument. - * - * @param func A function that returns class names to be toggled in the class attribute of each element in the matched set. Receives the index position of the element in the set, the old class value, and the switch as arguments. - * @param swtch A boolean value to determine whether the class should be added or removed. - */ - toggleClass(func: (index: number, className: string, swtch: boolean) => string, swtch?: boolean): JQuery; - - /** - * Get the current value of the first element in the set of matched elements. - */ - val(): any; - /** - * Set the value of each element in the set of matched elements. - * - * @param value A string of text or an array of strings corresponding to the value of each matched element to set as selected/checked. - */ - val(value: string|string[]): JQuery; - /** - * Set the value of each element in the set of matched elements. - * - * @param func A function returning the value to set. this is the current element. Receives the index position of the element in the set and the old value as arguments. - */ - val(func: (index: number, value: string) => string): JQuery; - - - /** - * Get the value of style properties for the first element in the set of matched elements. - * - * @param propertyName A CSS property. - */ - css(propertyName: string): string; - /** - * Set one or more CSS properties for the set of matched elements. - * - * @param propertyName A CSS property name. - * @param value A value to set for the property. - */ - css(propertyName: string, value: string|number): JQuery; - /** - * Set one or more CSS properties for the set of matched elements. - * - * @param propertyName A CSS property name. - * @param value A function returning the value to set. this is the current element. Receives the index position of the element in the set and the old value as arguments. - */ - css(propertyName: string, value: (index: number, value: string) => string|number): JQuery; - /** - * Set one or more CSS properties for the set of matched elements. - * - * @param properties An object of property-value pairs to set. - */ - css(properties: Object): JQuery; - - /** - * Get the current computed height for the first element in the set of matched elements. - */ - height(): number; - /** - * Set the CSS height of every matched element. - * - * @param value An integer representing the number of pixels, or an integer with an optional unit of measure appended (as a string). - */ - height(value: number|string): JQuery; - /** - * Set the CSS height of every matched element. - * - * @param func A function returning the height to set. Receives the index position of the element in the set and the old height as arguments. Within the function, this refers to the current element in the set. - */ - height(func: (index: number, height: number) => number|string): JQuery; - - /** - * Get the current computed height for the first element in the set of matched elements, including padding but not border. - */ - innerHeight(): number; - - /** - * Sets the inner height on elements in the set of matched elements, including padding but not border. - * - * @param value An integer representing the number of pixels, or an integer along with an optional unit of measure appended (as a string). - */ - innerHeight(height: number|string): JQuery; - - /** - * Get the current computed width for the first element in the set of matched elements, including padding but not border. - */ - innerWidth(): number; - - /** - * Sets the inner width on elements in the set of matched elements, including padding but not border. - * - * @param value An integer representing the number of pixels, or an integer along with an optional unit of measure appended (as a string). - */ - innerWidth(width: number|string): JQuery; - - /** - * Get the current coordinates of the first element in the set of matched elements, relative to the document. - */ - offset(): JQueryCoordinates; - /** - * An object containing the properties top and left, which are integers indicating the new top and left coordinates for the elements. - * - * @param coordinates An object containing the properties top and left, which are integers indicating the new top and left coordinates for the elements. - */ - offset(coordinates: JQueryCoordinates): JQuery; - /** - * An object containing the properties top and left, which are integers indicating the new top and left coordinates for the elements. - * - * @param func A function to return the coordinates to set. Receives the index of the element in the collection as the first argument and the current coordinates as the second argument. The function should return an object with the new top and left properties. - */ - offset(func: (index: number, coords: JQueryCoordinates) => JQueryCoordinates): JQuery; - - /** - * Get the current computed height for the first element in the set of matched elements, including padding, border, and optionally margin. Returns an integer (without "px") representation of the value or null if called on an empty set of elements. - * - * @param includeMargin A Boolean indicating whether to include the element's margin in the calculation. - */ - outerHeight(includeMargin?: boolean): number; - - /** - * Sets the outer height on elements in the set of matched elements, including padding and border. - * - * @param value An integer representing the number of pixels, or an integer along with an optional unit of measure appended (as a string). - */ - outerHeight(height: number|string): JQuery; - - /** - * Get the current computed width for the first element in the set of matched elements, including padding and border. - * - * @param includeMargin A Boolean indicating whether to include the element's margin in the calculation. - */ - outerWidth(includeMargin?: boolean): number; - - /** - * Sets the outer width on elements in the set of matched elements, including padding and border. - * - * @param value An integer representing the number of pixels, or an integer along with an optional unit of measure appended (as a string). - */ - outerWidth(width: number|string): JQuery; - - /** - * Get the current coordinates of the first element in the set of matched elements, relative to the offset parent. - */ - position(): JQueryCoordinates; - - /** - * Get the current horizontal position of the scroll bar for the first element in the set of matched elements or set the horizontal position of the scroll bar for every matched element. - */ - scrollLeft(): number; - /** - * Set the current horizontal position of the scroll bar for each of the set of matched elements. - * - * @param value An integer indicating the new position to set the scroll bar to. - */ - scrollLeft(value: number): JQuery; - - /** - * Get the current vertical position of the scroll bar for the first element in the set of matched elements or set the vertical position of the scroll bar for every matched element. - */ - scrollTop(): number; - /** - * Set the current vertical position of the scroll bar for each of the set of matched elements. - * - * @param value An integer indicating the new position to set the scroll bar to. - */ - scrollTop(value: number): JQuery; - - /** - * Get the current computed width for the first element in the set of matched elements. - */ - width(): number; - /** - * Set the CSS width of each element in the set of matched elements. - * - * @param value An integer representing the number of pixels, or an integer along with an optional unit of measure appended (as a string). - */ - width(value: number|string): JQuery; - /** - * Set the CSS width of each element in the set of matched elements. - * - * @param func A function returning the width to set. Receives the index position of the element in the set and the old width as arguments. Within the function, this refers to the current element in the set. - */ - width(func: (index: number, width: number) => number|string): JQuery; - - /** - * Remove from the queue all items that have not yet been run. - * - * @param queueName A string containing the name of the queue. Defaults to fx, the standard effects queue. - */ - clearQueue(queueName?: string): JQuery; - - /** - * Store arbitrary data associated with the matched elements. - * - * @param key A string naming the piece of data to set. - * @param value The new data value; it can be any Javascript type including Array or Object. - */ - data(key: string, value: any): JQuery; - /** - * Store arbitrary data associated with the matched elements. - * - * @param obj An object of key-value pairs of data to update. - */ - data(obj: { [key: string]: any; }): JQuery; - /** - * Return the value at the named data store for the first element in the jQuery collection, as set by data(name, value) or by an HTML5 data-* attribute. - * - * @param key Name of the data stored. - */ - data(key: string): any; - /** - * Return the value at the named data store for the first element in the jQuery collection, as set by data(name, value) or by an HTML5 data-* attribute. - */ - data(): any; - - /** - * Execute the next function on the queue for the matched elements. - * - * @param queueName A string containing the name of the queue. Defaults to fx, the standard effects queue. - */ - dequeue(queueName?: string): JQuery; - - /** - * Remove a previously-stored piece of data. - * - * @param name A string naming the piece of data to delete or space-separated string naming the pieces of data to delete. - */ - removeData(name: string): JQuery; - /** - * Remove a previously-stored piece of data. - * - * @param list An array of strings naming the pieces of data to delete. - */ - removeData(list: string[]): JQuery; - - /** - * Return a Promise object to observe when all actions of a certain type bound to the collection, queued or not, have finished. - * - * @param type The type of queue that needs to be observed. (default: fx) - * @param target Object onto which the promise methods have to be attached - */ - promise(type?: string, target?: Object): JQueryPromise; - - /** - * Perform a custom animation of a set of CSS properties. - * - * @param properties An object of CSS properties and values that the animation will move toward. - * @param duration A string or number determining how long the animation will run. - * @param complete A function to call once the animation is complete. - */ - animate(properties: Object, duration?: string|number, complete?: Function): JQuery; - /** - * Perform a custom animation of a set of CSS properties. - * - * @param properties An object of CSS properties and values that the animation will move toward. - * @param duration A string or number determining how long the animation will run. - * @param easing A string indicating which easing function to use for the transition. (default: swing) - * @param complete A function to call once the animation is complete. - */ - animate(properties: Object, duration?: string|number, easing?: string, complete?: Function): JQuery; - /** - * Perform a custom animation of a set of CSS properties. - * - * @param properties An object of CSS properties and values that the animation will move toward. - * @param options A map of additional options to pass to the method. - */ - animate(properties: Object, options: JQueryAnimationOptions): JQuery; - - /** - * Set a timer to delay execution of subsequent items in the queue. - * - * @param duration An integer indicating the number of milliseconds to delay execution of the next item in the queue. - * @param queueName A string containing the name of the queue. Defaults to fx, the standard effects queue. - */ - delay(duration: number, queueName?: string): JQuery; - - /** - * Display the matched elements by fading them to opaque. - * - * @param duration A string or number determining how long the animation will run. - * @param complete A function to call once the animation is complete. - */ - fadeIn(duration?: number|string, complete?: Function): JQuery; - /** - * Display the matched elements by fading them to opaque. - * - * @param duration A string or number determining how long the animation will run. - * @param easing A string indicating which easing function to use for the transition. - * @param complete A function to call once the animation is complete. - */ - fadeIn(duration?: number|string, easing?: string, complete?: Function): JQuery; - /** - * Display the matched elements by fading them to opaque. - * - * @param options A map of additional options to pass to the method. - */ - fadeIn(options: JQueryAnimationOptions): JQuery; - - /** - * Hide the matched elements by fading them to transparent. - * - * @param duration A string or number determining how long the animation will run. - * @param complete A function to call once the animation is complete. - */ - fadeOut(duration?: number|string, complete?: Function): JQuery; - /** - * Hide the matched elements by fading them to transparent. - * - * @param duration A string or number determining how long the animation will run. - * @param easing A string indicating which easing function to use for the transition. - * @param complete A function to call once the animation is complete. - */ - fadeOut(duration?: number|string, easing?: string, complete?: Function): JQuery; - /** - * Hide the matched elements by fading them to transparent. - * - * @param options A map of additional options to pass to the method. - */ - fadeOut(options: JQueryAnimationOptions): JQuery; - - /** - * Adjust the opacity of the matched elements. - * - * @param duration A string or number determining how long the animation will run. - * @param opacity A number between 0 and 1 denoting the target opacity. - * @param complete A function to call once the animation is complete. - */ - fadeTo(duration: string|number, opacity: number, complete?: Function): JQuery; - /** - * Adjust the opacity of the matched elements. - * - * @param duration A string or number determining how long the animation will run. - * @param opacity A number between 0 and 1 denoting the target opacity. - * @param easing A string indicating which easing function to use for the transition. - * @param complete A function to call once the animation is complete. - */ - fadeTo(duration: string|number, opacity: number, easing?: string, complete?: Function): JQuery; - - /** - * Display or hide the matched elements by animating their opacity. - * - * @param duration A string or number determining how long the animation will run. - * @param complete A function to call once the animation is complete. - */ - fadeToggle(duration?: number|string, complete?: Function): JQuery; - /** - * Display or hide the matched elements by animating their opacity. - * - * @param duration A string or number determining how long the animation will run. - * @param easing A string indicating which easing function to use for the transition. - * @param complete A function to call once the animation is complete. - */ - fadeToggle(duration?: number|string, easing?: string, complete?: Function): JQuery; - /** - * Display or hide the matched elements by animating their opacity. - * - * @param options A map of additional options to pass to the method. - */ - fadeToggle(options: JQueryAnimationOptions): JQuery; - - /** - * Stop the currently-running animation, remove all queued animations, and complete all animations for the matched elements. - * - * @param queue The name of the queue in which to stop animations. - */ - finish(queue?: string): JQuery; - - /** - * Hide the matched elements. - * - * @param duration A string or number determining how long the animation will run. - * @param complete A function to call once the animation is complete. - */ - hide(duration?: number|string, complete?: Function): JQuery; - /** - * Hide the matched elements. - * - * @param duration A string or number determining how long the animation will run. - * @param easing A string indicating which easing function to use for the transition. - * @param complete A function to call once the animation is complete. - */ - hide(duration?: number|string, easing?: string, complete?: Function): JQuery; - /** - * Hide the matched elements. - * - * @param options A map of additional options to pass to the method. - */ - hide(options: JQueryAnimationOptions): JQuery; - - /** - * Display the matched elements. - * - * @param duration A string or number determining how long the animation will run. - * @param complete A function to call once the animation is complete. - */ - show(duration?: number|string, complete?: Function): JQuery; - /** - * Display the matched elements. - * - * @param duration A string or number determining how long the animation will run. - * @param easing A string indicating which easing function to use for the transition. - * @param complete A function to call once the animation is complete. - */ - show(duration?: number|string, easing?: string, complete?: Function): JQuery; - /** - * Display the matched elements. - * - * @param options A map of additional options to pass to the method. - */ - show(options: JQueryAnimationOptions): JQuery; - - /** - * Display the matched elements with a sliding motion. - * - * @param duration A string or number determining how long the animation will run. - * @param complete A function to call once the animation is complete. - */ - slideDown(duration?: number|string, complete?: Function): JQuery; - /** - * Display the matched elements with a sliding motion. - * - * @param duration A string or number determining how long the animation will run. - * @param easing A string indicating which easing function to use for the transition. - * @param complete A function to call once the animation is complete. - */ - slideDown(duration?: number|string, easing?: string, complete?: Function): JQuery; - /** - * Display the matched elements with a sliding motion. - * - * @param options A map of additional options to pass to the method. - */ - slideDown(options: JQueryAnimationOptions): JQuery; - - /** - * Display or hide the matched elements with a sliding motion. - * - * @param duration A string or number determining how long the animation will run. - * @param complete A function to call once the animation is complete. - */ - slideToggle(duration?: number|string, complete?: Function): JQuery; - /** - * Display or hide the matched elements with a sliding motion. - * - * @param duration A string or number determining how long the animation will run. - * @param easing A string indicating which easing function to use for the transition. - * @param complete A function to call once the animation is complete. - */ - slideToggle(duration?: number|string, easing?: string, complete?: Function): JQuery; - /** - * Display or hide the matched elements with a sliding motion. - * - * @param options A map of additional options to pass to the method. - */ - slideToggle(options: JQueryAnimationOptions): JQuery; - - /** - * Hide the matched elements with a sliding motion. - * - * @param duration A string or number determining how long the animation will run. - * @param complete A function to call once the animation is complete. - */ - slideUp(duration?: number|string, complete?: Function): JQuery; - /** - * Hide the matched elements with a sliding motion. - * - * @param duration A string or number determining how long the animation will run. - * @param easing A string indicating which easing function to use for the transition. - * @param complete A function to call once the animation is complete. - */ - slideUp(duration?: number|string, easing?: string, complete?: Function): JQuery; - /** - * Hide the matched elements with a sliding motion. - * - * @param options A map of additional options to pass to the method. - */ - slideUp(options: JQueryAnimationOptions): JQuery; - - /** - * Stop the currently-running animation on the matched elements. - * - * @param clearQueue A Boolean indicating whether to remove queued animation as well. Defaults to false. - * @param jumpToEnd A Boolean indicating whether to complete the current animation immediately. Defaults to false. - */ - stop(clearQueue?: boolean, jumpToEnd?: boolean): JQuery; - /** - * Stop the currently-running animation on the matched elements. - * - * @param queue The name of the queue in which to stop animations. - * @param clearQueue A Boolean indicating whether to remove queued animation as well. Defaults to false. - * @param jumpToEnd A Boolean indicating whether to complete the current animation immediately. Defaults to false. - */ - stop(queue?: string, clearQueue?: boolean, jumpToEnd?: boolean): JQuery; - - /** - * Display or hide the matched elements. - * - * @param duration A string or number determining how long the animation will run. - * @param complete A function to call once the animation is complete. - */ - toggle(duration?: number|string, complete?: Function): JQuery; - /** - * Display or hide the matched elements. - * - * @param duration A string or number determining how long the animation will run. - * @param easing A string indicating which easing function to use for the transition. - * @param complete A function to call once the animation is complete. - */ - toggle(duration?: number|string, easing?: string, complete?: Function): JQuery; - /** - * Display or hide the matched elements. - * - * @param options A map of additional options to pass to the method. - */ - toggle(options: JQueryAnimationOptions): JQuery; - /** - * Display or hide the matched elements. - * - * @param showOrHide A Boolean indicating whether to show or hide the elements. - */ - toggle(showOrHide: boolean): JQuery; - - /** - * Attach a handler to an event for the elements. - * - * @param eventType A string containing one or more DOM event types, such as "click" or "submit," or custom event names. - * @param eventData An object containing data that will be passed to the event handler. - * @param handler A function to execute each time the event is triggered. - */ - bind(eventType: string, eventData: any, handler: (eventObject: JQueryEventObject) => any): JQuery; - /** - * Attach a handler to an event for the elements. - * - * @param eventType A string containing one or more DOM event types, such as "click" or "submit," or custom event names. - * @param handler A function to execute each time the event is triggered. - */ - bind(eventType: string, handler: (eventObject: JQueryEventObject) => any): JQuery; - /** - * Attach a handler to an event for the elements. - * - * @param eventType A string containing one or more DOM event types, such as "click" or "submit," or custom event names. - * @param eventData An object containing data that will be passed to the event handler. - * @param preventBubble Setting the third argument to false will attach a function that prevents the default action from occurring and stops the event from bubbling. The default is true. - */ - bind(eventType: string, eventData: any, preventBubble: boolean): JQuery; - /** - * Attach a handler to an event for the elements. - * - * @param eventType A string containing one or more DOM event types, such as "click" or "submit," or custom event names. - * @param preventBubble Setting the third argument to false will attach a function that prevents the default action from occurring and stops the event from bubbling. The default is true. - */ - bind(eventType: string, preventBubble: boolean): JQuery; - /** - * Attach a handler to an event for the elements. - * - * @param events An object containing one or more DOM event types and functions to execute for them. - */ - bind(events: any): JQuery; - - /** - * Trigger the "blur" event on an element - */ - blur(): JQuery; - /** - * Bind an event handler to the "blur" JavaScript event - * - * @param handler A function to execute each time the event is triggered. - */ - blur(handler: (eventObject: JQueryEventObject) => any): JQuery; - /** - * Bind an event handler to the "blur" JavaScript event - * - * @param eventData An object containing data that will be passed to the event handler. - * @param handler A function to execute each time the event is triggered. - */ - blur(eventData?: any, handler?: (eventObject: JQueryEventObject) => any): JQuery; - - /** - * Trigger the "change" event on an element. - */ - change(): JQuery; - /** - * Bind an event handler to the "change" JavaScript event - * - * @param handler A function to execute each time the event is triggered. - */ - change(handler: (eventObject: JQueryEventObject) => any): JQuery; - /** - * Bind an event handler to the "change" JavaScript event - * - * @param eventData An object containing data that will be passed to the event handler. - * @param handler A function to execute each time the event is triggered. - */ - change(eventData?: any, handler?: (eventObject: JQueryEventObject) => any): JQuery; - - /** - * Trigger the "click" event on an element. - */ - click(): JQuery; - /** - * Bind an event handler to the "click" JavaScript event - * - * @param eventData An object containing data that will be passed to the event handler. - */ - click(handler: (eventObject: JQueryEventObject) => any): JQuery; - /** - * Bind an event handler to the "click" JavaScript event - * - * @param eventData An object containing data that will be passed to the event handler. - * @param handler A function to execute each time the event is triggered. - */ - click(eventData?: any, handler?: (eventObject: JQueryEventObject) => any): JQuery; - - /** - * Trigger the "dblclick" event on an element. - */ - dblclick(): JQuery; - /** - * Bind an event handler to the "dblclick" JavaScript event - * - * @param handler A function to execute each time the event is triggered. - */ - dblclick(handler: (eventObject: JQueryEventObject) => any): JQuery; - /** - * Bind an event handler to the "dblclick" JavaScript event - * - * @param eventData An object containing data that will be passed to the event handler. - * @param handler A function to execute each time the event is triggered. - */ - dblclick(eventData?: any, handler?: (eventObject: JQueryEventObject) => any): JQuery; - - delegate(selector: any, eventType: string, handler: (eventObject: JQueryEventObject) => any): JQuery; - delegate(selector: any, eventType: string, eventData: any, handler: (eventObject: JQueryEventObject) => any): JQuery; - - /** - * Trigger the "focus" event on an element. - */ - focus(): JQuery; - /** - * Bind an event handler to the "focus" JavaScript event - * - * @param handler A function to execute each time the event is triggered. - */ - focus(handler: (eventObject: JQueryEventObject) => any): JQuery; - /** - * Bind an event handler to the "focus" JavaScript event - * - * @param eventData An object containing data that will be passed to the event handler. - * @param handler A function to execute each time the event is triggered. - */ - focus(eventData?: any, handler?: (eventObject: JQueryEventObject) => any): JQuery; - - /** - * Bind an event handler to the "focusin" JavaScript event - * - * @param handler A function to execute each time the event is triggered. - */ - focusin(handler: (eventObject: JQueryEventObject) => any): JQuery; - /** - * Bind an event handler to the "focusin" JavaScript event - * - * @param eventData An object containing data that will be passed to the event handler. - * @param handler A function to execute each time the event is triggered. - */ - focusin(eventData: Object, handler: (eventObject: JQueryEventObject) => any): JQuery; - - /** - * Bind an event handler to the "focusout" JavaScript event - * - * @param handler A function to execute each time the event is triggered. - */ - focusout(handler: (eventObject: JQueryEventObject) => any): JQuery; - /** - * Bind an event handler to the "focusout" JavaScript event - * - * @param eventData An object containing data that will be passed to the event handler. - * @param handler A function to execute each time the event is triggered. - */ - focusout(eventData: Object, handler: (eventObject: JQueryEventObject) => any): JQuery; - - /** - * Bind two handlers to the matched elements, to be executed when the mouse pointer enters and leaves the elements. - * - * @param handlerIn A function to execute when the mouse pointer enters the element. - * @param handlerOut A function to execute when the mouse pointer leaves the element. - */ - hover(handlerIn: (eventObject: JQueryEventObject) => any, handlerOut: (eventObject: JQueryEventObject) => any): JQuery; - /** - * Bind a single handler to the matched elements, to be executed when the mouse pointer enters or leaves the elements. - * - * @param handlerInOut A function to execute when the mouse pointer enters or leaves the element. - */ - hover(handlerInOut: (eventObject: JQueryEventObject) => any): JQuery; - - /** - * Trigger the "keydown" event on an element. - */ - keydown(): JQuery; - /** - * Bind an event handler to the "keydown" JavaScript event - * - * @param handler A function to execute each time the event is triggered. - */ - keydown(handler: (eventObject: JQueryKeyEventObject) => any): JQuery; - /** - * Bind an event handler to the "keydown" JavaScript event - * - * @param eventData An object containing data that will be passed to the event handler. - * @param handler A function to execute each time the event is triggered. - */ - keydown(eventData?: any, handler?: (eventObject: JQueryKeyEventObject) => any): JQuery; - - /** - * Trigger the "keypress" event on an element. - */ - keypress(): JQuery; - /** - * Bind an event handler to the "keypress" JavaScript event - * - * @param handler A function to execute each time the event is triggered. - */ - keypress(handler: (eventObject: JQueryKeyEventObject) => any): JQuery; - /** - * Bind an event handler to the "keypress" JavaScript event - * - * @param eventData An object containing data that will be passed to the event handler. - * @param handler A function to execute each time the event is triggered. - */ - keypress(eventData?: any, handler?: (eventObject: JQueryKeyEventObject) => any): JQuery; - - /** - * Trigger the "keyup" event on an element. - */ - keyup(): JQuery; - /** - * Bind an event handler to the "keyup" JavaScript event - * - * @param handler A function to execute each time the event is triggered. - */ - keyup(handler: (eventObject: JQueryKeyEventObject) => any): JQuery; - /** - * Bind an event handler to the "keyup" JavaScript event - * - * @param eventData An object containing data that will be passed to the event handler. - * @param handler A function to execute each time the event is triggered. - */ - keyup(eventData?: any, handler?: (eventObject: JQueryKeyEventObject) => any): JQuery; - - /** - * Bind an event handler to the "load" JavaScript event. - * - * @param handler A function to execute when the event is triggered. - */ - load(handler: (eventObject: JQueryEventObject) => any): JQuery; - /** - * Bind an event handler to the "load" JavaScript event. - * - * @param eventData An object containing data that will be passed to the event handler. - * @param handler A function to execute when the event is triggered. - */ - load(eventData?: any, handler?: (eventObject: JQueryEventObject) => any): JQuery; - - /** - * Trigger the "mousedown" event on an element. - */ - mousedown(): JQuery; - /** - * Bind an event handler to the "mousedown" JavaScript event. - * - * @param handler A function to execute when the event is triggered. - */ - mousedown(handler: (eventObject: JQueryMouseEventObject) => any): JQuery; - /** - * Bind an event handler to the "mousedown" JavaScript event. - * - * @param eventData An object containing data that will be passed to the event handler. - * @param handler A function to execute when the event is triggered. - */ - mousedown(eventData: Object, handler: (eventObject: JQueryMouseEventObject) => any): JQuery; - - /** - * Trigger the "mouseenter" event on an element. - */ - mouseenter(): JQuery; - /** - * Bind an event handler to be fired when the mouse enters an element. - * - * @param handler A function to execute when the event is triggered. - */ - mouseenter(handler: (eventObject: JQueryMouseEventObject) => any): JQuery; - /** - * Bind an event handler to be fired when the mouse enters an element. - * - * @param eventData An object containing data that will be passed to the event handler. - * @param handler A function to execute when the event is triggered. - */ - mouseenter(eventData: Object, handler: (eventObject: JQueryMouseEventObject) => any): JQuery; - - /** - * Trigger the "mouseleave" event on an element. - */ - mouseleave(): JQuery; - /** - * Bind an event handler to be fired when the mouse leaves an element. - * - * @param handler A function to execute when the event is triggered. - */ - mouseleave(handler: (eventObject: JQueryMouseEventObject) => any): JQuery; - /** - * Bind an event handler to be fired when the mouse leaves an element. - * - * @param eventData An object containing data that will be passed to the event handler. - * @param handler A function to execute when the event is triggered. - */ - mouseleave(eventData: Object, handler: (eventObject: JQueryMouseEventObject) => any): JQuery; - - /** - * Trigger the "mousemove" event on an element. - */ - mousemove(): JQuery; - /** - * Bind an event handler to the "mousemove" JavaScript event. - * - * @param handler A function to execute when the event is triggered. - */ - mousemove(handler: (eventObject: JQueryMouseEventObject) => any): JQuery; - /** - * Bind an event handler to the "mousemove" JavaScript event. - * - * @param eventData An object containing data that will be passed to the event handler. - * @param handler A function to execute when the event is triggered. - */ - mousemove(eventData: Object, handler: (eventObject: JQueryMouseEventObject) => any): JQuery; - - /** - * Trigger the "mouseout" event on an element. - */ - mouseout(): JQuery; - /** - * Bind an event handler to the "mouseout" JavaScript event. - * - * @param handler A function to execute when the event is triggered. - */ - mouseout(handler: (eventObject: JQueryMouseEventObject) => any): JQuery; - /** - * Bind an event handler to the "mouseout" JavaScript event. - * - * @param eventData An object containing data that will be passed to the event handler. - * @param handler A function to execute when the event is triggered. - */ - mouseout(eventData: Object, handler: (eventObject: JQueryMouseEventObject) => any): JQuery; - - /** - * Trigger the "mouseover" event on an element. - */ - mouseover(): JQuery; - /** - * Bind an event handler to the "mouseover" JavaScript event. - * - * @param handler A function to execute when the event is triggered. - */ - mouseover(handler: (eventObject: JQueryMouseEventObject) => any): JQuery; - /** - * Bind an event handler to the "mouseover" JavaScript event. - * - * @param eventData An object containing data that will be passed to the event handler. - * @param handler A function to execute when the event is triggered. - */ - mouseover(eventData: Object, handler: (eventObject: JQueryMouseEventObject) => any): JQuery; - - /** - * Trigger the "mouseup" event on an element. - */ - mouseup(): JQuery; - /** - * Bind an event handler to the "mouseup" JavaScript event. - * - * @param handler A function to execute when the event is triggered. - */ - mouseup(handler: (eventObject: JQueryMouseEventObject) => any): JQuery; - /** - * Bind an event handler to the "mouseup" JavaScript event. - * - * @param eventData An object containing data that will be passed to the event handler. - * @param handler A function to execute when the event is triggered. - */ - mouseup(eventData: Object, handler: (eventObject: JQueryMouseEventObject) => any): JQuery; - - /** - * Remove an event handler. - */ - off(): JQuery; - /** - * Remove an event handler. - * - * @param events One or more space-separated event types and optional namespaces, or just namespaces, such as "click", "keydown.myPlugin", or ".myPlugin". - * @param selector A selector which should match the one originally passed to .on() when attaching event handlers. - * @param handler A handler function previously attached for the event(s), or the special value false. - */ - off(events: string, selector?: string, handler?: (eventObject: JQueryEventObject) => any): JQuery; - /** - * Remove an event handler. - * - * @param events One or more space-separated event types and optional namespaces, or just namespaces, such as "click", "keydown.myPlugin", or ".myPlugin". - * @param handler A handler function previously attached for the event(s), or the special value false. - */ - off(events: string, handler: (eventObject: JQueryEventObject) => any): JQuery; - /** - * Remove an event handler. - * - * @param events An object where the string keys represent one or more space-separated event types and optional namespaces, and the values represent handler functions previously attached for the event(s). - * @param selector A selector which should match the one originally passed to .on() when attaching event handlers. - */ - off(events: { [key: string]: any; }, selector?: string): JQuery; - - /** - * Attach an event handler function for one or more events to the selected elements. - * - * @param events One or more space-separated event types and optional namespaces, such as "click" or "keydown.myPlugin". - * @param handler A function to execute when the event is triggered. The value false is also allowed as a shorthand for a function that simply does return false. Rest parameter args is for optional parameters passed to jQuery.trigger(). Note that the actual parameters on the event handler function must be marked as optional (? syntax). - */ - on(events: string, handler: (eventObject: JQueryEventObject, ...args: any[]) => any): JQuery; - /** - * Attach an event handler function for one or more events to the selected elements. - * - * @param events One or more space-separated event types and optional namespaces, such as "click" or "keydown.myPlugin". - * @param data Data to be passed to the handler in event.data when an event is triggered. - * @param handler A function to execute when the event is triggered. The value false is also allowed as a shorthand for a function that simply does return false. - */ - on(events: string, data : any, handler: (eventObject: JQueryEventObject, ...args: any[]) => any): JQuery; - /** - * Attach an event handler function for one or more events to the selected elements. - * - * @param events One or more space-separated event types and optional namespaces, such as "click" or "keydown.myPlugin". - * @param selector A selector string to filter the descendants of the selected elements that trigger the event. If the selector is null or omitted, the event is always triggered when it reaches the selected element. - * @param handler A function to execute when the event is triggered. The value false is also allowed as a shorthand for a function that simply does return false. - */ - on(events: string, selector: string, handler: (eventObject: JQueryEventObject, ...eventData: any[]) => any): JQuery; - /** - * Attach an event handler function for one or more events to the selected elements. - * - * @param events One or more space-separated event types and optional namespaces, such as "click" or "keydown.myPlugin". - * @param selector A selector string to filter the descendants of the selected elements that trigger the event. If the selector is null or omitted, the event is always triggered when it reaches the selected element. - * @param data Data to be passed to the handler in event.data when an event is triggered. - * @param handler A function to execute when the event is triggered. The value false is also allowed as a shorthand for a function that simply does return false. - */ - on(events: string, selector: string, data: any, handler: (eventObject: JQueryEventObject, ...eventData: any[]) => any): JQuery; - /** - * Attach an event handler function for one or more events to the selected elements. - * - * @param events An object in which the string keys represent one or more space-separated event types and optional namespaces, and the values represent a handler function to be called for the event(s). - * @param selector A selector string to filter the descendants of the selected elements that will call the handler. If the selector is null or omitted, the handler is always called when it reaches the selected element. - * @param data Data to be passed to the handler in event.data when an event occurs. - */ - on(events: { [key: string]: any; }, selector?: string, data?: any): JQuery; - /** - * Attach an event handler function for one or more events to the selected elements. - * - * @param events An object in which the string keys represent one or more space-separated event types and optional namespaces, and the values represent a handler function to be called for the event(s). - * @param data Data to be passed to the handler in event.data when an event occurs. - */ - on(events: { [key: string]: any; }, data?: any): JQuery; - - /** - * Attach a handler to an event for the elements. The handler is executed at most once per element per event type. - * - * @param events A string containing one or more JavaScript event types, such as "click" or "submit," or custom event names. - * @param handler A function to execute at the time the event is triggered. - */ - one(events: string, handler: (eventObject: JQueryEventObject) => any): JQuery; - /** - * Attach a handler to an event for the elements. The handler is executed at most once per element per event type. - * - * @param events A string containing one or more JavaScript event types, such as "click" or "submit," or custom event names. - * @param data An object containing data that will be passed to the event handler. - * @param handler A function to execute at the time the event is triggered. - */ - one(events: string, data: Object, handler: (eventObject: JQueryEventObject) => any): JQuery; - - /** - * Attach a handler to an event for the elements. The handler is executed at most once per element per event type. - * - * @param events One or more space-separated event types and optional namespaces, such as "click" or "keydown.myPlugin". - * @param selector A selector string to filter the descendants of the selected elements that trigger the event. If the selector is null or omitted, the event is always triggered when it reaches the selected element. - * @param handler A function to execute when the event is triggered. The value false is also allowed as a shorthand for a function that simply does return false. - */ - one(events: string, selector: string, handler: (eventObject: JQueryEventObject) => any): JQuery; - /** - * Attach a handler to an event for the elements. The handler is executed at most once per element per event type. - * - * @param events One or more space-separated event types and optional namespaces, such as "click" or "keydown.myPlugin". - * @param selector A selector string to filter the descendants of the selected elements that trigger the event. If the selector is null or omitted, the event is always triggered when it reaches the selected element. - * @param data Data to be passed to the handler in event.data when an event is triggered. - * @param handler A function to execute when the event is triggered. The value false is also allowed as a shorthand for a function that simply does return false. - */ - one(events: string, selector: string, data: any, handler: (eventObject: JQueryEventObject) => any): JQuery; - - /** - * Attach a handler to an event for the elements. The handler is executed at most once per element per event type. - * - * @param events An object in which the string keys represent one or more space-separated event types and optional namespaces, and the values represent a handler function to be called for the event(s). - * @param selector A selector string to filter the descendants of the selected elements that will call the handler. If the selector is null or omitted, the handler is always called when it reaches the selected element. - * @param data Data to be passed to the handler in event.data when an event occurs. - */ - one(events: { [key: string]: any; }, selector?: string, data?: any): JQuery; - - /** - * Attach a handler to an event for the elements. The handler is executed at most once per element per event type. - * - * @param events An object in which the string keys represent one or more space-separated event types and optional namespaces, and the values represent a handler function to be called for the event(s). - * @param data Data to be passed to the handler in event.data when an event occurs. - */ - one(events: { [key: string]: any; }, data?: any): JQuery; - - - /** - * Specify a function to execute when the DOM is fully loaded. - * - * @param handler A function to execute after the DOM is ready. - */ - ready(handler: Function): JQuery; - - /** - * Trigger the "resize" event on an element. - */ - resize(): JQuery; - /** - * Bind an event handler to the "resize" JavaScript event. - * - * @param handler A function to execute each time the event is triggered. - */ - resize(handler: (eventObject: JQueryEventObject) => any): JQuery; - /** - * Bind an event handler to the "resize" JavaScript event. - * - * @param eventData An object containing data that will be passed to the event handler. - * @param handler A function to execute each time the event is triggered. - */ - resize(eventData: Object, handler: (eventObject: JQueryEventObject) => any): JQuery; - - /** - * Trigger the "scroll" event on an element. - */ - scroll(): JQuery; - /** - * Bind an event handler to the "scroll" JavaScript event. - * - * @param handler A function to execute each time the event is triggered. - */ - scroll(handler: (eventObject: JQueryEventObject) => any): JQuery; - /** - * Bind an event handler to the "scroll" JavaScript event. - * - * @param eventData An object containing data that will be passed to the event handler. - * @param handler A function to execute each time the event is triggered. - */ - scroll(eventData: Object, handler: (eventObject: JQueryEventObject) => any): JQuery; - - /** - * Trigger the "select" event on an element. - */ - select(): JQuery; - /** - * Bind an event handler to the "select" JavaScript event. - * - * @param handler A function to execute each time the event is triggered. - */ - select(handler: (eventObject: JQueryEventObject) => any): JQuery; - /** - * Bind an event handler to the "select" JavaScript event. - * - * @param eventData An object containing data that will be passed to the event handler. - * @param handler A function to execute each time the event is triggered. - */ - select(eventData: Object, handler: (eventObject: JQueryEventObject) => any): JQuery; - - /** - * Trigger the "submit" event on an element. - */ - submit(): JQuery; - /** - * Bind an event handler to the "submit" JavaScript event - * - * @param handler A function to execute each time the event is triggered. - */ - submit(handler: (eventObject: JQueryEventObject) => any): JQuery; - /** - * Bind an event handler to the "submit" JavaScript event - * - * @param eventData An object containing data that will be passed to the event handler. - * @param handler A function to execute each time the event is triggered. - */ - submit(eventData?: any, handler?: (eventObject: JQueryEventObject) => any): JQuery; - - /** - * Execute all handlers and behaviors attached to the matched elements for the given event type. - * - * @param eventType A string containing a JavaScript event type, such as click or submit. - * @param extraParameters Additional parameters to pass along to the event handler. - */ - trigger(eventType: string, extraParameters?: any[]|Object): JQuery; - /** - * Execute all handlers and behaviors attached to the matched elements for the given event type. - * - * @param event A jQuery.Event object. - * @param extraParameters Additional parameters to pass along to the event handler. - */ - trigger(event: JQueryEventObject, extraParameters?: any[]|Object): JQuery; - - /** - * Execute all handlers attached to an element for an event. - * - * @param eventType A string containing a JavaScript event type, such as click or submit. - * @param extraParameters An array of additional parameters to pass along to the event handler. - */ - triggerHandler(eventType: string, ...extraParameters: any[]): Object; - - /** - * Remove a previously-attached event handler from the elements. - * - * @param eventType A string containing a JavaScript event type, such as click or submit. - * @param handler The function that is to be no longer executed. - */ - unbind(eventType?: string, handler?: (eventObject: JQueryEventObject) => any): JQuery; - /** - * Remove a previously-attached event handler from the elements. - * - * @param eventType A string containing a JavaScript event type, such as click or submit. - * @param fls Unbinds the corresponding 'return false' function that was bound using .bind( eventType, false ). - */ - unbind(eventType: string, fls: boolean): JQuery; - /** - * Remove a previously-attached event handler from the elements. - * - * @param evt A JavaScript event object as passed to an event handler. - */ - unbind(evt: any): JQuery; - - /** - * Remove a handler from the event for all elements which match the current selector, based upon a specific set of root elements. - */ - undelegate(): JQuery; - /** - * Remove a handler from the event for all elements which match the current selector, based upon a specific set of root elements. - * - * @param selector A selector which will be used to filter the event results. - * @param eventType A string containing a JavaScript event type, such as "click" or "keydown" - * @param handler A function to execute at the time the event is triggered. - */ - undelegate(selector: string, eventType: string, handler?: (eventObject: JQueryEventObject) => any): JQuery; - /** - * Remove a handler from the event for all elements which match the current selector, based upon a specific set of root elements. - * - * @param selector A selector which will be used to filter the event results. - * @param events An object of one or more event types and previously bound functions to unbind from them. - */ - undelegate(selector: string, events: Object): JQuery; - /** - * Remove a handler from the event for all elements which match the current selector, based upon a specific set of root elements. - * - * @param namespace A string containing a namespace to unbind all events from. - */ - undelegate(namespace: string): JQuery; - - /** - * Bind an event handler to the "unload" JavaScript event. (DEPRECATED from v1.8) - * - * @param handler A function to execute when the event is triggered. - */ - unload(handler: (eventObject: JQueryEventObject) => any): JQuery; - /** - * Bind an event handler to the "unload" JavaScript event. (DEPRECATED from v1.8) - * - * @param eventData A plain object of data that will be passed to the event handler. - * @param handler A function to execute when the event is triggered. - */ - unload(eventData?: any, handler?: (eventObject: JQueryEventObject) => any): JQuery; - - /** - * The DOM node context originally passed to jQuery(); if none was passed then context will likely be the document. (DEPRECATED from v1.10) - */ - context: Element; - - jquery: string; - - /** - * Bind an event handler to the "error" JavaScript event. (DEPRECATED from v1.8) - * - * @param handler A function to execute when the event is triggered. - */ - error(handler: (eventObject: JQueryEventObject) => any): JQuery; - /** - * Bind an event handler to the "error" JavaScript event. (DEPRECATED from v1.8) - * - * @param eventData A plain object of data that will be passed to the event handler. - * @param handler A function to execute when the event is triggered. - */ - error(eventData: any, handler: (eventObject: JQueryEventObject) => any): JQuery; - - /** - * Add a collection of DOM elements onto the jQuery stack. - * - * @param elements An array of elements to push onto the stack and make into a new jQuery object. - */ - pushStack(elements: any[]): JQuery; - /** - * Add a collection of DOM elements onto the jQuery stack. - * - * @param elements An array of elements to push onto the stack and make into a new jQuery object. - * @param name The name of a jQuery method that generated the array of elements. - * @param arguments The arguments that were passed in to the jQuery method (for serialization). - */ - pushStack(elements: any[], name: string, arguments: any[]): JQuery; - - /** - * Insert content, specified by the parameter, after each element in the set of matched elements. - * - * param content1 HTML string, DOM element, array of elements, or jQuery object to insert after each element in the set of matched elements. - * param content2 One or more additional DOM elements, arrays of elements, HTML strings, or jQuery objects to insert after each element in the set of matched elements. - */ - after(content1: JQuery|any[]|Element|Text|string, ...content2: any[]): JQuery; - /** - * Insert content, specified by the parameter, after each element in the set of matched elements. - * - * param func A function that returns an HTML string, DOM element(s), or jQuery object to insert after each element in the set of matched elements. Receives the index position of the element in the set as an argument. Within the function, this refers to the current element in the set. - */ - after(func: (index: number, html: string) => string|Element|JQuery): JQuery; - - /** - * Insert content, specified by the parameter, to the end of each element in the set of matched elements. - * - * param content1 DOM element, array of elements, HTML string, or jQuery object to insert at the end of each element in the set of matched elements. - * param content2 One or more additional DOM elements, arrays of elements, HTML strings, or jQuery objects to insert at the end of each element in the set of matched elements. - */ - append(content1: JQuery|any[]|Element|Text|string, ...content2: any[]): JQuery; - /** - * Insert content, specified by the parameter, to the end of each element in the set of matched elements. - * - * param func A function that returns an HTML string, DOM element(s), or jQuery object to insert at the end of each element in the set of matched elements. Receives the index position of the element in the set and the old HTML value of the element as arguments. Within the function, this refers to the current element in the set. - */ - append(func: (index: number, html: string) => string|Element|JQuery): JQuery; - - /** - * Insert every element in the set of matched elements to the end of the target. - * - * @param target A selector, element, HTML string, array of elements, or jQuery object; the matched set of elements will be inserted at the end of the element(s) specified by this parameter. - */ - appendTo(target: JQuery|any[]|Element|string): JQuery; - - /** - * Insert content, specified by the parameter, before each element in the set of matched elements. - * - * param content1 HTML string, DOM element, array of elements, or jQuery object to insert before each element in the set of matched elements. - * param content2 One or more additional DOM elements, arrays of elements, HTML strings, or jQuery objects to insert before each element in the set of matched elements. - */ - before(content1: JQuery|any[]|Element|Text|string, ...content2: any[]): JQuery; - /** - * Insert content, specified by the parameter, before each element in the set of matched elements. - * - * param func A function that returns an HTML string, DOM element(s), or jQuery object to insert before each element in the set of matched elements. Receives the index position of the element in the set as an argument. Within the function, this refers to the current element in the set. - */ - before(func: (index: number, html: string) => string|Element|JQuery): JQuery; - - /** - * Create a deep copy of the set of matched elements. - * - * param withDataAndEvents A Boolean indicating whether event handlers and data should be copied along with the elements. The default value is false. - * param deepWithDataAndEvents A Boolean indicating whether event handlers and data for all children of the cloned element should be copied. By default its value matches the first argument's value (which defaults to false). - */ - clone(withDataAndEvents?: boolean, deepWithDataAndEvents?: boolean): JQuery; - - /** - * Remove the set of matched elements from the DOM. - * - * param selector A selector expression that filters the set of matched elements to be removed. - */ - detach(selector?: string): JQuery; - - /** - * Remove all child nodes of the set of matched elements from the DOM. - */ - empty(): JQuery; - - /** - * Insert every element in the set of matched elements after the target. - * - * param target A selector, element, array of elements, HTML string, or jQuery object; the matched set of elements will be inserted after the element(s) specified by this parameter. - */ - insertAfter(target: JQuery|any[]|Element|Text|string): JQuery; - - /** - * Insert every element in the set of matched elements before the target. - * - * param target A selector, element, array of elements, HTML string, or jQuery object; the matched set of elements will be inserted before the element(s) specified by this parameter. - */ - insertBefore(target: JQuery|any[]|Element|Text|string): JQuery; - - /** - * Insert content, specified by the parameter, to the beginning of each element in the set of matched elements. - * - * param content1 DOM element, array of elements, HTML string, or jQuery object to insert at the beginning of each element in the set of matched elements. - * param content2 One or more additional DOM elements, arrays of elements, HTML strings, or jQuery objects to insert at the beginning of each element in the set of matched elements. - */ - prepend(content1: JQuery|any[]|Element|Text|string, ...content2: any[]): JQuery; - /** - * Insert content, specified by the parameter, to the beginning of each element in the set of matched elements. - * - * param func A function that returns an HTML string, DOM element(s), or jQuery object to insert at the beginning of each element in the set of matched elements. Receives the index position of the element in the set and the old HTML value of the element as arguments. Within the function, this refers to the current element in the set. - */ - prepend(func: (index: number, html: string) => string|Element|JQuery): JQuery; - - /** - * Insert every element in the set of matched elements to the beginning of the target. - * - * @param target A selector, element, HTML string, array of elements, or jQuery object; the matched set of elements will be inserted at the beginning of the element(s) specified by this parameter. - */ - prependTo(target: JQuery|any[]|Element|string): JQuery; - - /** - * Remove the set of matched elements from the DOM. - * - * @param selector A selector expression that filters the set of matched elements to be removed. - */ - remove(selector?: string): JQuery; - - /** - * Replace each target element with the set of matched elements. - * - * @param target A selector string, jQuery object, DOM element, or array of elements indicating which element(s) to replace. - */ - replaceAll(target: JQuery|any[]|Element|string): JQuery; - - /** - * Replace each element in the set of matched elements with the provided new content and return the set of elements that was removed. - * - * param newContent The content to insert. May be an HTML string, DOM element, array of DOM elements, or jQuery object. - */ - replaceWith(newContent: JQuery|any[]|Element|Text|string): JQuery; - /** - * Replace each element in the set of matched elements with the provided new content and return the set of elements that was removed. - * - * param func A function that returns content with which to replace the set of matched elements. - */ - replaceWith(func: () => Element|JQuery): JQuery; - - /** - * Get the combined text contents of each element in the set of matched elements, including their descendants. - */ - text(): string; - /** - * Set the content of each element in the set of matched elements to the specified text. - * - * @param text The text to set as the content of each matched element. When Number or Boolean is supplied, it will be converted to a String representation. - */ - text(text: string|number|boolean): JQuery; - /** - * Set the content of each element in the set of matched elements to the specified text. - * - * @param func A function returning the text content to set. Receives the index position of the element in the set and the old text value as arguments. - */ - text(func: (index: number, text: string) => string): JQuery; - - /** - * Retrieve all the elements contained in the jQuery set, as an array. - */ - toArray(): any[]; - - /** - * Remove the parents of the set of matched elements from the DOM, leaving the matched elements in their place. - */ - unwrap(): JQuery; - - /** - * Wrap an HTML structure around each element in the set of matched elements. - * - * @param wrappingElement A selector, element, HTML string, or jQuery object specifying the structure to wrap around the matched elements. - */ - wrap(wrappingElement: JQuery|Element|string): JQuery; - /** - * Wrap an HTML structure around each element in the set of matched elements. - * - * @param func A callback function returning the HTML content or jQuery object to wrap around the matched elements. Receives the index position of the element in the set as an argument. Within the function, this refers to the current element in the set. - */ - wrap(func: (index: number) => string|JQuery): JQuery; - - /** - * Wrap an HTML structure around all elements in the set of matched elements. - * - * @param wrappingElement A selector, element, HTML string, or jQuery object specifying the structure to wrap around the matched elements. - */ - wrapAll(wrappingElement: JQuery|Element|string): JQuery; - wrapAll(func: (index: number) => string): JQuery; - - /** - * Wrap an HTML structure around the content of each element in the set of matched elements. - * - * @param wrappingElement An HTML snippet, selector expression, jQuery object, or DOM element specifying the structure to wrap around the content of the matched elements. - */ - wrapInner(wrappingElement: JQuery|Element|string): JQuery; - /** - * Wrap an HTML structure around the content of each element in the set of matched elements. - * - * @param func A callback function which generates a structure to wrap around the content of the matched elements. Receives the index position of the element in the set as an argument. Within the function, this refers to the current element in the set. - */ - wrapInner(func: (index: number) => string): JQuery; - - /** - * Iterate over a jQuery object, executing a function for each matched element. - * - * @param func A function to execute for each matched element. - */ - each(func: (index: number, elem: Element) => any): JQuery; - - /** - * Retrieve one of the elements matched by the jQuery object. - * - * @param index A zero-based integer indicating which element to retrieve. - */ - get(index: number): HTMLElement; - /** - * Retrieve the elements matched by the jQuery object. - */ - get(): any[]; - - /** - * Search for a given element from among the matched elements. - */ - index(): number; - /** - * Search for a given element from among the matched elements. - * - * @param selector A selector representing a jQuery collection in which to look for an element. - */ - index(selector: string|JQuery|Element): number; - - /** - * The number of elements in the jQuery object. - */ - length: number; - /** - * A selector representing selector passed to jQuery(), if any, when creating the original set. - * version deprecated: 1.7, removed: 1.9 - */ - selector: string; - [index: string]: any; - [index: number]: HTMLElement; - - /** - * Add elements to the set of matched elements. - * - * @param selector A string representing a selector expression to find additional elements to add to the set of matched elements. - * @param context The point in the document at which the selector should begin matching; similar to the context argument of the $(selector, context) method. - */ - add(selector: string, context?: Element): JQuery; - /** - * Add elements to the set of matched elements. - * - * @param elements One or more elements to add to the set of matched elements. - */ - add(...elements: Element[]): JQuery; - /** - * Add elements to the set of matched elements. - * - * @param html An HTML fragment to add to the set of matched elements. - */ - add(html: string): JQuery; - /** - * Add elements to the set of matched elements. - * - * @param obj An existing jQuery object to add to the set of matched elements. - */ - add(obj: JQuery): JQuery; - - /** - * Get the children of each element in the set of matched elements, optionally filtered by a selector. - * - * @param selector A string containing a selector expression to match elements against. - */ - children(selector?: string): JQuery; - - /** - * For each element in the set, get the first element that matches the selector by testing the element itself and traversing up through its ancestors in the DOM tree. - * - * @param selector A string containing a selector expression to match elements against. - */ - closest(selector: string): JQuery; - /** - * For each element in the set, get the first element that matches the selector by testing the element itself and traversing up through its ancestors in the DOM tree. - * - * @param selector A string containing a selector expression to match elements against. - * @param context A DOM element within which a matching element may be found. If no context is passed in then the context of the jQuery set will be used instead. - */ - closest(selector: string, context?: Element): JQuery; - /** - * For each element in the set, get the first element that matches the selector by testing the element itself and traversing up through its ancestors in the DOM tree. - * - * @param obj A jQuery object to match elements against. - */ - closest(obj: JQuery): JQuery; - /** - * For each element in the set, get the first element that matches the selector by testing the element itself and traversing up through its ancestors in the DOM tree. - * - * @param element An element to match elements against. - */ - closest(element: Element): JQuery; - - /** - * Get an array of all the elements and selectors matched against the current element up through the DOM tree. - * - * @param selectors An array or string containing a selector expression to match elements against (can also be a jQuery object). - * @param context A DOM element within which a matching element may be found. If no context is passed in then the context of the jQuery set will be used instead. - */ - closest(selectors: any, context?: Element): any[]; - - /** - * Get the children of each element in the set of matched elements, including text and comment nodes. - */ - contents(): JQuery; - - /** - * End the most recent filtering operation in the current chain and return the set of matched elements to its previous state. - */ - end(): JQuery; - - /** - * Reduce the set of matched elements to the one at the specified index. - * - * @param index An integer indicating the 0-based position of the element. OR An integer indicating the position of the element, counting backwards from the last element in the set. - * - */ - eq(index: number): JQuery; - - /** - * Reduce the set of matched elements to those that match the selector or pass the function's test. - * - * @param selector A string containing a selector expression to match the current set of elements against. - */ - filter(selector: string): JQuery; - /** - * Reduce the set of matched elements to those that match the selector or pass the function's test. - * - * @param func A function used as a test for each element in the set. this is the current DOM element. - */ - filter(func: (index: number, element: Element) => any): JQuery; - /** - * Reduce the set of matched elements to those that match the selector or pass the function's test. - * - * @param element An element to match the current set of elements against. - */ - filter(element: Element): JQuery; - /** - * Reduce the set of matched elements to those that match the selector or pass the function's test. - * - * @param obj An existing jQuery object to match the current set of elements against. - */ - filter(obj: JQuery): JQuery; - - /** - * Get the descendants of each element in the current set of matched elements, filtered by a selector, jQuery object, or element. - * - * @param selector A string containing a selector expression to match elements against. - */ - find(selector: string): JQuery; - /** - * Get the descendants of each element in the current set of matched elements, filtered by a selector, jQuery object, or element. - * - * @param element An element to match elements against. - */ - find(element: Element): JQuery; - /** - * Get the descendants of each element in the current set of matched elements, filtered by a selector, jQuery object, or element. - * - * @param obj A jQuery object to match elements against. - */ - find(obj: JQuery): JQuery; - - /** - * Reduce the set of matched elements to the first in the set. - */ - first(): JQuery; - - /** - * Reduce the set of matched elements to those that have a descendant that matches the selector or DOM element. - * - * @param selector A string containing a selector expression to match elements against. - */ - has(selector: string): JQuery; - /** - * Reduce the set of matched elements to those that have a descendant that matches the selector or DOM element. - * - * @param contained A DOM element to match elements against. - */ - has(contained: Element): JQuery; - - /** - * Check the current matched set of elements against a selector, element, or jQuery object and return true if at least one of these elements matches the given arguments. - * - * @param selector A string containing a selector expression to match elements against. - */ - is(selector: string): boolean; - /** - * Check the current matched set of elements against a selector, element, or jQuery object and return true if at least one of these elements matches the given arguments. - * - * @param func A function used as a test for the set of elements. It accepts one argument, index, which is the element's index in the jQuery collection.Within the function, this refers to the current DOM element. - */ - is(func: (index: number, element: Element) => boolean): boolean; - /** - * Check the current matched set of elements against a selector, element, or jQuery object and return true if at least one of these elements matches the given arguments. - * - * @param obj An existing jQuery object to match the current set of elements against. - */ - is(obj: JQuery): boolean; - /** - * Check the current matched set of elements against a selector, element, or jQuery object and return true if at least one of these elements matches the given arguments. - * - * @param elements One or more elements to match the current set of elements against. - */ - is(elements: any): boolean; - - /** - * Reduce the set of matched elements to the final one in the set. - */ - last(): JQuery; - - /** - * Pass each element in the current matched set through a function, producing a new jQuery object containing the return values. - * - * @param callback A function object that will be invoked for each element in the current set. - */ - map(callback: (index: number, domElement: Element) => any): JQuery; - - /** - * Get the immediately following sibling of each element in the set of matched elements. If a selector is provided, it retrieves the next sibling only if it matches that selector. - * - * @param selector A string containing a selector expression to match elements against. - */ - next(selector?: string): JQuery; - - /** - * Get all following siblings of each element in the set of matched elements, optionally filtered by a selector. - * - * @param selector A string containing a selector expression to match elements against. - */ - nextAll(selector?: string): JQuery; - - /** - * Get all following siblings of each element up to but not including the element matched by the selector, DOM node, or jQuery object passed. - * - * @param selector A string containing a selector expression to indicate where to stop matching following sibling elements. - * @param filter A string containing a selector expression to match elements against. - */ - nextUntil(selector?: string, filter?: string): JQuery; - /** - * Get all following siblings of each element up to but not including the element matched by the selector, DOM node, or jQuery object passed. - * - * @param element A DOM node or jQuery object indicating where to stop matching following sibling elements. - * @param filter A string containing a selector expression to match elements against. - */ - nextUntil(element?: Element, filter?: string): JQuery; - /** - * Get all following siblings of each element up to but not including the element matched by the selector, DOM node, or jQuery object passed. - * - * @param obj A DOM node or jQuery object indicating where to stop matching following sibling elements. - * @param filter A string containing a selector expression to match elements against. - */ - nextUntil(obj?: JQuery, filter?: string): JQuery; - - /** - * Remove elements from the set of matched elements. - * - * @param selector A string containing a selector expression to match elements against. - */ - not(selector: string): JQuery; - /** - * Remove elements from the set of matched elements. - * - * @param func A function used as a test for each element in the set. this is the current DOM element. - */ - not(func: (index: number, element: Element) => boolean): JQuery; - /** - * Remove elements from the set of matched elements. - * - * @param elements One or more DOM elements to remove from the matched set. - */ - not(...elements: Element[]): JQuery; - /** - * Remove elements from the set of matched elements. - * - * @param obj An existing jQuery object to match the current set of elements against. - */ - not(obj: JQuery): JQuery; - - /** - * Get the closest ancestor element that is positioned. - */ - offsetParent(): JQuery; - - /** - * Get the parent of each element in the current set of matched elements, optionally filtered by a selector. - * - * @param selector A string containing a selector expression to match elements against. - */ - parent(selector?: string): JQuery; - - /** - * Get the ancestors of each element in the current set of matched elements, optionally filtered by a selector. - * - * @param selector A string containing a selector expression to match elements against. - */ - parents(selector?: string): JQuery; - - /** - * Get the ancestors of each element in the current set of matched elements, up to but not including the element matched by the selector, DOM node, or jQuery object. - * - * @param selector A string containing a selector expression to indicate where to stop matching ancestor elements. - * @param filter A string containing a selector expression to match elements against. - */ - parentsUntil(selector?: string, filter?: string): JQuery; - /** - * Get the ancestors of each element in the current set of matched elements, up to but not including the element matched by the selector, DOM node, or jQuery object. - * - * @param element A DOM node or jQuery object indicating where to stop matching ancestor elements. - * @param filter A string containing a selector expression to match elements against. - */ - parentsUntil(element?: Element, filter?: string): JQuery; - /** - * Get the ancestors of each element in the current set of matched elements, up to but not including the element matched by the selector, DOM node, or jQuery object. - * - * @param obj A DOM node or jQuery object indicating where to stop matching ancestor elements. - * @param filter A string containing a selector expression to match elements against. - */ - parentsUntil(obj?: JQuery, filter?: string): JQuery; - - /** - * Get the immediately preceding sibling of each element in the set of matched elements, optionally filtered by a selector. - * - * @param selector A string containing a selector expression to match elements against. - */ - prev(selector?: string): JQuery; - - /** - * Get all preceding siblings of each element in the set of matched elements, optionally filtered by a selector. - * - * @param selector A string containing a selector expression to match elements against. - */ - prevAll(selector?: string): JQuery; - - /** - * Get all preceding siblings of each element up to but not including the element matched by the selector, DOM node, or jQuery object. - * - * @param selector A string containing a selector expression to indicate where to stop matching preceding sibling elements. - * @param filter A string containing a selector expression to match elements against. - */ - prevUntil(selector?: string, filter?: string): JQuery; - /** - * Get all preceding siblings of each element up to but not including the element matched by the selector, DOM node, or jQuery object. - * - * @param element A DOM node or jQuery object indicating where to stop matching preceding sibling elements. - * @param filter A string containing a selector expression to match elements against. - */ - prevUntil(element?: Element, filter?: string): JQuery; - /** - * Get all preceding siblings of each element up to but not including the element matched by the selector, DOM node, or jQuery object. - * - * @param obj A DOM node or jQuery object indicating where to stop matching preceding sibling elements. - * @param filter A string containing a selector expression to match elements against. - */ - prevUntil(obj?: JQuery, filter?: string): JQuery; - - /** - * Get the siblings of each element in the set of matched elements, optionally filtered by a selector. - * - * @param selector A string containing a selector expression to match elements against. - */ - siblings(selector?: string): JQuery; - - /** - * Reduce the set of matched elements to a subset specified by a range of indices. - * - * @param start An integer indicating the 0-based position at which the elements begin to be selected. If negative, it indicates an offset from the end of the set. - * @param end An integer indicating the 0-based position at which the elements stop being selected. If negative, it indicates an offset from the end of the set. If omitted, the range continues until the end of the set. - */ - slice(start: number, end?: number): JQuery; - - /** - * Show the queue of functions to be executed on the matched elements. - * - * @param queueName A string containing the name of the queue. Defaults to fx, the standard effects queue. - */ - queue(queueName?: string): any[]; - /** - * Manipulate the queue of functions to be executed, once for each matched element. - * - * @param newQueue An array of functions to replace the current queue contents. - */ - queue(newQueue: Function[]): JQuery; - /** - * Manipulate the queue of functions to be executed, once for each matched element. - * - * @param callback The new function to add to the queue, with a function to call that will dequeue the next item. - */ - queue(callback: Function): JQuery; - /** - * Manipulate the queue of functions to be executed, once for each matched element. - * - * @param queueName A string containing the name of the queue. Defaults to fx, the standard effects queue. - * @param newQueue An array of functions to replace the current queue contents. - */ - queue(queueName: string, newQueue: Function[]): JQuery; - /** - * Manipulate the queue of functions to be executed, once for each matched element. - * - * @param queueName A string containing the name of the queue. Defaults to fx, the standard effects queue. - * @param callback The new function to add to the queue, with a function to call that will dequeue the next item. - */ - queue(queueName: string, callback: Function): JQuery; -} -declare module "jquery" { - export = $; -} -declare var jQuery: JQueryStatic; -declare var $: JQueryStatic; diff --git a/dist/globals.js b/lib/typings/jsx.d.ts similarity index 100% rename from dist/globals.js rename to lib/typings/jsx.d.ts diff --git a/lib/typings/linter.d.ts b/lib/typings/linter.d.ts new file mode 100644 index 000000000..d3d104635 --- /dev/null +++ b/lib/typings/linter.d.ts @@ -0,0 +1,22 @@ +export interface Linter { + deleteMessages() + setMessages(messages: LinterMessage[]) + dispose() +} + +export interface LinterConfig { + name: string +} + +export interface LinterMessage { + type: "Error" | "Warning" | "Info", + text?: string, + html?: string, + filePath?: string, + range?: TextBuffer.IRange, + // trace?: Array // We don't care about this so I have this commented out +} + +export interface LinterRegistry { + register(config: LinterConfig): Linter +} diff --git a/lib/typings/minimatch/minimatch.d.ts b/lib/typings/minimatch/minimatch.d.ts deleted file mode 100644 index a79c6ff11..000000000 --- a/lib/typings/minimatch/minimatch.d.ts +++ /dev/null @@ -1,64 +0,0 @@ -// Type definitions for Minimatch 2.0.8 -// Project: https://github.com/isaacs/minimatch -// Definitions by: vvakame -// Definitions: https://github.com/borisyankov/DefinitelyTyped - -declare module "minimatch" { - - function M(target: string, pattern: string, options?: M.IOptions): boolean; - - module M { - function match(list: string[], pattern: string, options?: IOptions): string[]; - function filter(pattern: string, options?: IOptions): (element: string, indexed: number, array: string[]) => boolean; - function makeRe(pattern: string, options?: IOptions): RegExp; - - var Minimatch: IMinimatchStatic; - - interface IOptions { - debug?: boolean; - nobrace?: boolean; - noglobstar?: boolean; - dot?: boolean; - noext?: boolean; - nocase?: boolean; - nonull?: boolean; - matchBase?: boolean; - nocomment?: boolean; - nonegate?: boolean; - flipNegate?: boolean; - } - - interface IMinimatchStatic { - new (pattern: string, options?: IOptions): IMinimatch; - prototype: IMinimatch; - } - - interface IMinimatch { - pattern: string; - options: IOptions; - /** 2-dimensional array of regexp or string expressions. */ - set: any[][]; // (RegExp | string)[][] - regexp: RegExp; - negate: boolean; - comment: boolean; - empty: boolean; - - makeRe(): RegExp; // regexp or boolean - match(fname: string): boolean; - matchOne(files: string[], pattern: string[], partial: boolean): boolean; - - /** Deprecated. For internal use. */ - debug(): void; - /** Deprecated. For internal use. */ - make(): void; - /** Deprecated. For internal use. */ - parseNegate(): void; - /** Deprecated. For internal use. */ - braceExpand(pattern: string, options: IOptions): void; - /** Deprecated. For internal use. */ - parse(pattern: string, isSub?: boolean): void; - } - } - - export = M; -} diff --git a/lib/typings/mixto/mixto.d.ts b/lib/typings/mixto/mixto.d.ts deleted file mode 100644 index 1edf8bef1..000000000 --- a/lib/typings/mixto/mixto.d.ts +++ /dev/null @@ -1,16 +0,0 @@ -// Type definitions for mixto -// Project: https://github.com/atom/mixto -// Definitions by: vvakame -// Definitions: https://github.com/borisyankov/DefinitelyTyped - -declare module Mixto { - interface IMixinStatic { - includeInto(constructor:any):void; - extend(object:any):void; - } -} - -declare module "mixto" { - var _tmp:Mixto.IMixinStatic; - export = _tmp; -} diff --git a/lib/typings/mkdirp/mkdirp.d.ts b/lib/typings/mkdirp/mkdirp.d.ts deleted file mode 100644 index c3fca38a2..000000000 --- a/lib/typings/mkdirp/mkdirp.d.ts +++ /dev/null @@ -1,15 +0,0 @@ -// Type definitions for mkdirp 0.3.0 -// Project: http://github.com/substack/node-mkdirp -// Definitions by: Bart van der Schoor -// Definitions: https://github.com/borisyankov/DefinitelyTyped - -declare module 'mkdirp' { - - function mkdirp(dir: string, cb: (err: any, made: string) => void): void; - function mkdirp(dir: string, flags: any, cb: (err: any, made: string) => void): void; - - module mkdirp { - function sync(dir: string, flags?: any): string; - } - export = mkdirp; -} diff --git a/lib/typings/mustache.d.ts b/lib/typings/mustache.d.ts deleted file mode 100644 index 46f16df19..000000000 --- a/lib/typings/mustache.d.ts +++ /dev/null @@ -1,11 +0,0 @@ -// Type definitions for Mustache 0.7 -// Project: https://github.com/janl/mustache.js -// Definitions by: Boris Yankov -// Definitions: https://github.com/borisyankov/DefinitelyTyped - - -/*tslint:disable unused*/ - -declare var Mustache: { - render(template: string, data: any): string; -}; diff --git a/lib/typings/q/Q.d.ts b/lib/typings/q/Q.d.ts deleted file mode 100644 index bd5a6f4bf..000000000 --- a/lib/typings/q/Q.d.ts +++ /dev/null @@ -1,317 +0,0 @@ -// Type definitions for Q -// Project: https://github.com/kriskowal/q -// Definitions by: Barrie Nemetchek , Andrew Gaspar , John Reilly -// Definitions: https://github.com/borisyankov/DefinitelyTyped - -/** - * If value is a Q promise, returns the promise. - * If value is a promise from another library it is coerced into a Q promise (where possible). - */ -declare function Q(promise: Q.IPromise): Q.Promise; -/** - * If value is not a promise, returns a promise that is fulfilled with value. - */ -declare function Q(value: T): Q.Promise; - -declare module Q { - interface IPromise { - then(onFulfill?: (value: T) => U | IPromise, onReject?: (error: any) => U | IPromise): IPromise; - } - - interface Deferred { - promise: Promise; - resolve(value: T): void; - reject(reason: any): void; - notify(value: any): void; - makeNodeResolver(): (reason: any, value: T) => void; - } - - interface Promise { - /** - * Like a finally clause, allows you to observe either the fulfillment or rejection of a promise, but to do so without modifying the final value. This is useful for collecting resources regardless of whether a job succeeded, like closing a database connection, shutting a server down, or deleting an unneeded key from an object. - - * finally returns a promise, which will become resolved with the same fulfillment value or rejection reason as promise. However, if callback returns a promise, the resolution of the returned promise will be delayed until the promise returned from callback is finished. - */ - fin(finallyCallback: () => any): Promise; - /** - * Like a finally clause, allows you to observe either the fulfillment or rejection of a promise, but to do so without modifying the final value. This is useful for collecting resources regardless of whether a job succeeded, like closing a database connection, shutting a server down, or deleting an unneeded key from an object. - - * finally returns a promise, which will become resolved with the same fulfillment value or rejection reason as promise. However, if callback returns a promise, the resolution of the returned promise will be delayed until the promise returned from callback is finished. - */ - finally(finallyCallback: () => any): Promise; - - /** - * The then method from the Promises/A+ specification, with an additional progress handler. - */ - then(onFulfill?: (value: T) => U | IPromise, onReject?: (error: any) => U | IPromise, onProgress?: Function): Promise; - - /** - * Like then, but "spreads" the array into a variadic fulfillment handler. If any of the promises in the array are rejected, instead calls onRejected with the first rejected promise's rejection reason. - * - * This is especially useful in conjunction with all - */ - spread(onFulfilled: Function, onRejected?: Function): Promise; - - fail(onRejected: (reason: any) => U | IPromise): Promise; - - /** - * A sugar method, equivalent to promise.then(undefined, onRejected). - */ - catch(onRejected: (reason: any) => U | IPromise): Promise; - - /** - * A sugar method, equivalent to promise.then(undefined, undefined, onProgress). - */ - progress(onProgress: (progress: any) => any): Promise; - - /** - * Much like then, but with different behavior around unhandled rejection. If there is an unhandled rejection, either because promise is rejected and no onRejected callback was provided, or because onFulfilled or onRejected threw an error or returned a rejected promise, the resulting rejection reason is thrown as an exception in a future turn of the event loop. - * - * This method should be used to terminate chains of promises that will not be passed elsewhere. Since exceptions thrown in then callbacks are consumed and transformed into rejections, exceptions at the end of the chain are easy to accidentally, silently ignore. By arranging for the exception to be thrown in a future turn of the event loop, so that it won't be caught, it causes an onerror event on the browser window, or an uncaughtException event on Node.js's process object. - * - * Exceptions thrown by done will have long stack traces, if Q.longStackSupport is set to true. If Q.onerror is set, exceptions will be delivered there instead of thrown in a future turn. - * - * The Golden Rule of done vs. then usage is: either return your promise to someone else, or if the chain ends with you, call done to terminate it. - */ - done(onFulfilled?: (value: T) => any, onRejected?: (reason: any) => any, onProgress?: (progress: any) => any): void; - - /** - * If callback is a function, assumes it's a Node.js-style callback, and calls it as either callback(rejectionReason) when/if promise becomes rejected, or as callback(null, fulfillmentValue) when/if promise becomes fulfilled. If callback is not a function, simply returns promise. - */ - nodeify(callback: (reason: any, value: any) => void): Promise; - - /** - * Returns a promise to get the named property of an object. Essentially equivalent to - * - * promise.then(function (o) { - * return o[propertyName]; - * }); - */ - get(propertyName: String): Promise; - set(propertyName: String, value: any): Promise; - delete(propertyName: String): Promise; - /** - * Returns a promise for the result of calling the named method of an object with the given array of arguments. The object itself is this in the function, just like a synchronous method call. Essentially equivalent to - * - * promise.then(function (o) { - * return o[methodName].apply(o, args); - * }); - */ - post(methodName: String, args: any[]): Promise; - /** - * Returns a promise for the result of calling the named method of an object with the given variadic arguments. The object itself is this in the function, just like a synchronous method call. - */ - invoke(methodName: String, ...args: any[]): Promise; - fapply(args: any[]): Promise; - fcall(...args: any[]): Promise; - - /** - * Returns a promise for an array of the property names of an object. Essentially equivalent to - * - * promise.then(function (o) { - * return Object.keys(o); - * }); - */ - keys(): Promise; - - /** - * A sugar method, equivalent to promise.then(function () { return value; }). - */ - thenResolve(value: U): Promise; - /** - * A sugar method, equivalent to promise.then(function () { throw reason; }). - */ - thenReject(reason: any): Promise; - timeout(ms: number, message?: string): Promise; - /** - * Returns a promise that will have the same result as promise, but will only be fulfilled or rejected after at least ms milliseconds have passed. - */ - delay(ms: number): Promise; - - /** - * Returns whether a given promise is in the fulfilled state. When the static version is used on non-promises, the result is always true. - */ - isFulfilled(): boolean; - /** - * Returns whether a given promise is in the rejected state. When the static version is used on non-promises, the result is always false. - */ - isRejected(): boolean; - /** - * Returns whether a given promise is in the pending state. When the static version is used on non-promises, the result is always false. - */ - isPending(): boolean; - - valueOf(): any; - - /** - * Returns a "state snapshot" object, which will be in one of three forms: - * - * - { state: "pending" } - * - { state: "fulfilled", value: } - * - { state: "rejected", reason: } - */ - inspect(): PromiseState; - } - - interface PromiseState { - /** - * "fulfilled", "rejected", "pending" - */ - state: string; - value?: T; - reason?: any; - } - - // If no value provided, returned promise will be of void type - export function when(): Promise; - - // if no fulfill, reject, or progress provided, returned promise will be of same type - export function when(value: T | IPromise): Promise; - - // If a non-promise value is provided, it will not reject or progress - export function when(value: T | IPromise, onFulfilled: (val: T) => U | IPromise, onRejected?: (reason: any) => U | IPromise, onProgress?: (progress: any) => any): Promise; - - /** - * Currently "impossible" (and I use the term loosely) to implement due to TypeScript limitations as it is now. - * See: https://github.com/Microsoft/TypeScript/issues/1784 for discussion on it. - */ - // export function try(method: Function, ...args: any[]): Promise; - - export function fbind(method: (...args: any[]) => T | IPromise, ...args: any[]): (...args: any[]) => Promise; - - export function fcall(method: (...args: any[]) => T, ...args: any[]): Promise; - - export function send(obj: any, functionName: string, ...args: any[]): Promise; - export function invoke(obj: any, functionName: string, ...args: any[]): Promise; - export function mcall(obj: any, functionName: string, ...args: any[]): Promise; - - export function denodeify(nodeFunction: Function, ...args: any[]): (...args: any[]) => Promise; - export function nbind(nodeFunction: Function, thisArg: any, ...args: any[]): (...args: any[]) => Promise; - export function nfbind(nodeFunction: Function, ...args: any[]): (...args: any[]) => Promise; - export function nfcall(nodeFunction: Function, ...args: any[]): Promise; - export function nfapply(nodeFunction: Function, args: any[]): Promise; - - export function ninvoke(nodeModule: any, functionName: string, ...args: any[]): Promise; - export function npost(nodeModule: any, functionName: string, args: any[]): Promise; - export function nsend(nodeModule: any, functionName: string, ...args: any[]): Promise; - export function nmcall(nodeModule: any, functionName: string, ...args: any[]): Promise; - - /** - * Returns a promise that is fulfilled with an array containing the fulfillment value of each promise, or is rejected with the same rejection reason as the first promise to be rejected. - */ - export function all(promises: IPromise[]): Promise; - - /** - * Returns a promise that is fulfilled with an array of promise state snapshots, but only after all the original promises have settled, i.e. become either fulfilled or rejected. - */ - export function allSettled(promises: IPromise[]): Promise[]>; - - export function allResolved(promises: IPromise[]): Promise[]>; - - /** - * Like then, but "spreads" the array into a variadic fulfillment handler. If any of the promises in the array are rejected, instead calls onRejected with the first rejected promise's rejection reason. - * This is especially useful in conjunction with all. - */ - export function spread(promises: IPromise[], onFulfilled: (...args: T[]) => U | IPromise, onRejected?: (reason: any) => U | IPromise): Promise; - - /** - * Returns a promise that will have the same result as promise, except that if promise is not fulfilled or rejected before ms milliseconds, the returned promise will be rejected with an Error with the given message. If message is not supplied, the message will be "Timed out after " + ms + " ms". - */ - export function timeout(promise: Promise, ms: number, message?: string): Promise; - - /** - * Returns a promise that will have the same result as promise, but will only be fulfilled or rejected after at least ms milliseconds have passed. - */ - export function delay(promise: Promise, ms: number): Promise; - /** - * Returns a promise that will have the same result as promise, but will only be fulfilled or rejected after at least ms milliseconds have passed. - */ - export function delay(value: T, ms: number): Promise; - /** - * Returns a promise that will be fulfilled with undefined after at least ms milliseconds have passed. - */ - export function delay(ms: number): Promise ; - /** - * Returns whether a given promise is in the fulfilled state. When the static version is used on non-promises, the result is always true. - */ - export function isFulfilled(promise: Promise): boolean; - /** - * Returns whether a given promise is in the rejected state. When the static version is used on non-promises, the result is always false. - */ - export function isRejected(promise: Promise): boolean; - /** - * Returns whether a given promise is in the pending state. When the static version is used on non-promises, the result is always false. - */ - export function isPending(promise: Promise): boolean; - - /** - * Returns a "deferred" object with a: - * promise property - * resolve(value) method - * reject(reason) method - * notify(value) method - * makeNodeResolver() method - */ - export function defer(): Deferred; - - /** - * Returns a promise that is rejected with reason. - */ - export function reject(reason?: any): Promise; - - export function Promise(resolver: (resolve: (val: T | IPromise) => void , reject: (reason: any) => void , notify: (progress: any) => void ) => void ): Promise; - - /** - * Creates a new version of func that accepts any combination of promise and non-promise values, converting them to their fulfillment values before calling the original func. The returned version also always returns a promise: if func does a return or throw, then Q.promised(func) will return fulfilled or rejected promise, respectively. - * - * This can be useful for creating functions that accept either promises or non-promise values, and for ensuring that the function always returns a promise even in the face of unintentional thrown exceptions. - */ - export function promised(callback: (...args: any[]) => T): (...args: any[]) => Promise; - - /** - * Returns whether the given value is a Q promise. - */ - export function isPromise(object: any): boolean; - /** - * Returns whether the given value is a promise (i.e. it's an object with a then function). - */ - export function isPromiseAlike(object: any): boolean; - /** - * Returns whether a given promise is in the pending state. When the static version is used on non-promises, the result is always false. - */ - export function isPending(object: any): boolean; - - /** - * This is an experimental tool for converting a generator function into a deferred function. This has the potential of reducing nested callbacks in engines that support yield. - */ - export function async(generatorFunction: any): (...args: any[]) => Promise; - export function nextTick(callback: Function): void; - - /** - * A settable property that will intercept any uncaught errors that would otherwise be thrown in the next tick of the event loop, usually as a result of done. Can be useful for getting the full stack trace of an error in browsers, which is not usually possible with window.onerror. - */ - export var onerror: (reason: any) => void; - /** - * A settable property that lets you turn on long stack trace support. If turned on, "stack jumps" will be tracked across asynchronous promise operations, so that if an uncaught error is thrown by done or a rejection reason's stack property is inspected in a rejection callback, a long stack trace is produced. - */ - export var longStackSupport: boolean; - - /** - * Calling resolve with a pending promise causes promise to wait on the passed promise, becoming fulfilled with its fulfillment value or rejected with its rejection reason (or staying pending forever, if the passed promise does). - * Calling resolve with a rejected promise causes promise to be rejected with the passed promise's rejection reason. - * Calling resolve with a fulfilled promise causes promise to be fulfilled with the passed promise's fulfillment value. - * Calling resolve with a non-promise value causes promise to be fulfilled with that value. - */ - export function resolve(object: IPromise): Promise; - /** - * Calling resolve with a pending promise causes promise to wait on the passed promise, becoming fulfilled with its fulfillment value or rejected with its rejection reason (or staying pending forever, if the passed promise does). - * Calling resolve with a rejected promise causes promise to be rejected with the passed promise's rejection reason. - * Calling resolve with a fulfilled promise causes promise to be fulfilled with the passed promise's fulfillment value. - * Calling resolve with a non-promise value causes promise to be fulfilled with that value. - */ - export function resolve(object: T): Promise; -} - -declare module "q" { - export = Q; -} diff --git a/lib/typings/react/react-jsx.d.ts b/lib/typings/react/react-jsx.d.ts deleted file mode 100644 index 7bcfa08ac..000000000 --- a/lib/typings/react/react-jsx.d.ts +++ /dev/null @@ -1,147 +0,0 @@ -// Type definitions for React v0.13.1 (JSX support) -// Project: http://facebook.github.io/react/ -// Definitions by: Asana , AssureSign , Microsoft -// Definitions: https://github.com/borisyankov/DefinitelyTyped -/// - -declare module JSX { - interface Element extends React.ReactElement { } - interface ElementClass extends React.Component { } - interface ElementAttributesProperty { props: {}; } - - interface IntrinsicElements { - // HTML - a: React.HTMLAttributes; - abbr: React.HTMLAttributes; - address: React.HTMLAttributes; - area: React.HTMLAttributes; - article: React.HTMLAttributes; - aside: React.HTMLAttributes; - audio: React.HTMLAttributes; - b: React.HTMLAttributes; - base: React.HTMLAttributes; - bdi: React.HTMLAttributes; - bdo: React.HTMLAttributes; - big: React.HTMLAttributes; - blockquote: React.HTMLAttributes; - body: React.HTMLAttributes; - br: React.HTMLAttributes; - button: React.HTMLAttributes; - canvas: React.HTMLAttributes; - caption: React.HTMLAttributes; - cite: React.HTMLAttributes; - code: React.HTMLAttributes; - col: React.HTMLAttributes; - colgroup: React.HTMLAttributes; - data: React.HTMLAttributes; - datalist: React.HTMLAttributes; - dd: React.HTMLAttributes; - del: React.HTMLAttributes; - details: React.HTMLAttributes; - dfn: React.HTMLAttributes; - dialog: React.HTMLAttributes; - div: React.HTMLAttributes; - dl: React.HTMLAttributes; - dt: React.HTMLAttributes; - em: React.HTMLAttributes; - embed: React.HTMLAttributes; - fieldset: React.HTMLAttributes; - figcaption: React.HTMLAttributes; - figure: React.HTMLAttributes; - footer: React.HTMLAttributes; - form: React.HTMLAttributes; - h1: React.HTMLAttributes; - h2: React.HTMLAttributes; - h3: React.HTMLAttributes; - h4: React.HTMLAttributes; - h5: React.HTMLAttributes; - h6: React.HTMLAttributes; - head: React.HTMLAttributes; - header: React.HTMLAttributes; - hr: React.HTMLAttributes; - html: React.HTMLAttributes; - i: React.HTMLAttributes; - iframe: React.HTMLAttributes; - img: React.HTMLAttributes; - input: React.HTMLAttributes; - ins: React.HTMLAttributes; - kbd: React.HTMLAttributes; - keygen: React.HTMLAttributes; - label: React.HTMLAttributes; - legend: React.HTMLAttributes; - li: React.HTMLAttributes; - link: React.HTMLAttributes; - main: React.HTMLAttributes; - map: React.HTMLAttributes; - mark: React.HTMLAttributes; - menu: React.HTMLAttributes; - menuitem: React.HTMLAttributes; - meta: React.HTMLAttributes; - meter: React.HTMLAttributes; - nav: React.HTMLAttributes; - noscript: React.HTMLAttributes; - object: React.HTMLAttributes; - ol: React.HTMLAttributes; - optgroup: React.HTMLAttributes; - option: React.HTMLAttributes; - output: React.HTMLAttributes; - p: React.HTMLAttributes; - param: React.HTMLAttributes; - picture: React.HTMLAttributes; - pre: React.HTMLAttributes; - progress: React.HTMLAttributes; - q: React.HTMLAttributes; - rp: React.HTMLAttributes; - rt: React.HTMLAttributes; - ruby: React.HTMLAttributes; - s: React.HTMLAttributes; - samp: React.HTMLAttributes; - script: React.HTMLAttributes; - section: React.HTMLAttributes; - select: React.HTMLAttributes; - small: React.HTMLAttributes; - source: React.HTMLAttributes; - span: React.HTMLAttributes; - strong: React.HTMLAttributes; - style: React.HTMLAttributes; - sub: React.HTMLAttributes; - summary: React.HTMLAttributes; - sup: React.HTMLAttributes; - table: React.HTMLAttributes; - tbody: React.HTMLAttributes; - td: React.HTMLAttributes; - textarea: React.HTMLAttributes; - tfoot: React.HTMLAttributes; - th: React.HTMLAttributes; - thead: React.HTMLAttributes; - time: React.HTMLAttributes; - title: React.HTMLAttributes; - tr: React.HTMLAttributes; - track: React.HTMLAttributes; - u: React.HTMLAttributes; - ul: React.HTMLAttributes; - "var": React.HTMLAttributes; - video: React.HTMLAttributes; - wbr: React.HTMLAttributes; - - // SVG - svg: React.SVGElementAttributes; - - circle: React.SVGAttributes; - defs: React.SVGAttributes; - ellipse: React.SVGAttributes; - g: React.SVGAttributes; - line: React.SVGAttributes; - linearGradient: React.SVGAttributes; - mask: React.SVGAttributes; - path: React.SVGAttributes; - pattern: React.SVGAttributes; - polygon: React.SVGAttributes; - polyline: React.SVGAttributes; - radialGradient: React.SVGAttributes; - rect: React.SVGAttributes; - stop: React.SVGAttributes; - text: React.SVGAttributes; - tspan: React.SVGAttributes; - } -} diff --git a/lib/typings/react/react.d.ts b/lib/typings/react/react.d.ts deleted file mode 100644 index b23a8240e..000000000 --- a/lib/typings/react/react.d.ts +++ /dev/null @@ -1,789 +0,0 @@ -// Type definitions for React v0.13.1 (internal and external module) -// Project: http://facebook.github.io/react/ -// Definitions by: Asana , AssureSign -// Definitions: https://github.com/borisyankov/DefinitelyTyped - -declare module React { - // - // React Elements - // ---------------------------------------------------------------------- - - type ReactType = ComponentClass | string; - - interface ReactElement

    { - type: string | ComponentClass

    ; - props: P; - key: string | number; - ref: string | ((component: Component) => any); - } - - interface ClassicElement

    extends ReactElement

    { - type: string | ClassicComponentClass

    ; - ref: string | ((component: ClassicComponent) => any); - } - - interface DOMElement

    extends ClassicElement

    { - type: string; - ref: string | ((component: DOMComponent

    ) => any); - } - - type HTMLElement = DOMElement; - type SVGElement = DOMElement; - - // - // Factories - // ---------------------------------------------------------------------- - - interface Factory

    { - (props?: P, ...children: ReactNode[]): ReactElement

    ; - } - - interface ClassicFactory

    extends Factory

    { - (props?: P, ...children: ReactNode[]): ClassicElement

    ; - } - - interface DOMFactory

    extends ClassicFactory

    { - (props?: P, ...children: ReactNode[]): DOMElement

    ; - } - - type HTMLFactory = DOMFactory; - type SVGFactory = DOMFactory; - - // - // React Nodes - // http://facebook.github.io/react/docs/glossary.html - // ---------------------------------------------------------------------- - - type ReactText = string | number; - type ReactChild = ReactElement | ReactText; - - // Should be Array but type aliases cannot be recursive - type ReactFragment = {} | Array; - type ReactNode = ReactChild | ReactFragment | boolean; - - // - // Top Level API - // ---------------------------------------------------------------------- - - function createClass(spec: ComponentSpec): ClassicComponentClass

    ; - - function createFactory

    (type: string): DOMFactory

    ; - function createFactory

    (type: ClassicComponentClass

    | string): ClassicFactory

    ; - function createFactory

    (type: ComponentClass

    ): Factory

    ; - - function createElement

    ( - type: string, - props?: P, - ...children: ReactNode[]): DOMElement

    ; - function createElement

    ( - type: ClassicComponentClass

    | string, - props?: P, - ...children: ReactNode[]): ClassicElement

    ; - function createElement

    ( - type: ComponentClass

    , - props?: P, - ...children: ReactNode[]): ReactElement

    ; - - function cloneElement

    ( - element: DOMElement

    , - props?: P, - ...children: ReactNode[]): DOMElement

    ; - function cloneElement

    ( - element: ClassicElement

    , - props?: P, - ...children: ReactNode[]): ClassicElement

    ; - function cloneElement

    ( - element: ReactElement

    , - props?: P, - ...children: ReactNode[]): ReactElement

    ; - - function render

    ( - element: DOMElement

    , - container: Element, - callback?: () => any): DOMComponent

    ; - function render( - element: ClassicElement

    , - container: Element, - callback?: () => any): ClassicComponent; - function render( - element: ReactElement

    , - container: Element, - callback?: () => any): Component; - - function unmountComponentAtNode(container: Element): boolean; - function renderToString(element: ReactElement): string; - function renderToStaticMarkup(element: ReactElement): string; - function isValidElement(object: {}): boolean; - function initializeTouchEvents(shouldUseTouch: boolean): void; - - function findDOMNode( - componentOrElement: Component | Element): TElement; - function findDOMNode( - componentOrElement: Component | Element): Element; - - var DOM: ReactDOM; - var PropTypes: ReactPropTypes; - var Children: ReactChildren; - - // - // Component API - // ---------------------------------------------------------------------- - - // Base component for plain JS classes - class Component implements ComponentLifecycle { - constructor(props?: P, context?: any); - setState(f: (prevState: S, props: P) => S, callback?: () => any): void; - setState(state: S, callback?: () => any): void; - forceUpdate(): void; - props: P; - state: S; - context: any; - refs: { - [key: string]: Component - }; - } - - interface ClassicComponent extends Component { - replaceState(nextState: S, callback?: () => any): void; - getDOMNode(): TElement; - getDOMNode(): Element; - isMounted(): boolean; - getInitialState?(): S; - setProps(nextProps: P, callback?: () => any): void; - replaceProps(nextProps: P, callback?: () => any): void; - } - - interface DOMComponent

    extends ClassicComponent { - tagName: string; - } - - type HTMLComponent = DOMComponent; - type SVGComponent = DOMComponent; - - interface ChildContextProvider { - getChildContext(): CC; - } - - // - // Class Interfaces - // ---------------------------------------------------------------------- - - interface ComponentClass

    { - new(props?: P, context?: any): Component; - propTypes?: ValidationMap

    ; - contextTypes?: ValidationMap; - childContextTypes?: ValidationMap; - defaultProps?: P; - } - - interface ClassicComponentClass

    extends ComponentClass

    { - new(props?: P, context?: any): ClassicComponent; - getDefaultProps?(): P; - displayName?: string; - } - - // - // Component Specs and Lifecycle - // ---------------------------------------------------------------------- - - interface ComponentLifecycle { - componentWillMount?(): void; - componentDidMount?(): void; - componentWillReceiveProps?(nextProps: P, nextContext: any): void; - shouldComponentUpdate?(nextProps: P, nextState: S, nextContext: any): boolean; - componentWillUpdate?(nextProps: P, nextState: S, nextContext: any): void; - componentDidUpdate?(prevProps: P, prevState: S, prevContext: any): void; - componentWillUnmount?(): void; - } - - interface Mixin extends ComponentLifecycle { - mixins?: Mixin; - statics?: { - [key: string]: any; - }; - - displayName?: string; - propTypes?: ValidationMap; - contextTypes?: ValidationMap; - childContextTypes?: ValidationMap - - getDefaultProps?(): P; - getInitialState?(): S; - } - - interface ComponentSpec extends Mixin { - render(): ReactElement; - } - - // - // Event System - // ---------------------------------------------------------------------- - - interface SyntheticEvent { - bubbles: boolean; - cancelable: boolean; - currentTarget: EventTarget; - defaultPrevented: boolean; - eventPhase: number; - isTrusted: boolean; - nativeEvent: Event; - preventDefault(): void; - stopPropagation(): void; - target: EventTarget; - timeStamp: Date; - type: string; - } - - interface DragEvent extends SyntheticEvent { - dataTransfer: DataTransfer; - } - - interface ClipboardEvent extends SyntheticEvent { - clipboardData: DataTransfer; - } - - interface KeyboardEvent extends SyntheticEvent { - altKey: boolean; - charCode: number; - ctrlKey: boolean; - getModifierState(key: string): boolean; - key: string; - keyCode: number; - locale: string; - location: number; - metaKey: boolean; - repeat: boolean; - shiftKey: boolean; - which: number; - } - - interface FocusEvent extends SyntheticEvent { - relatedTarget: EventTarget; - } - - interface FormEvent extends SyntheticEvent { - } - - interface MouseEvent extends SyntheticEvent { - altKey: boolean; - button: number; - buttons: number; - clientX: number; - clientY: number; - ctrlKey: boolean; - getModifierState(key: string): boolean; - metaKey: boolean; - pageX: number; - pageY: number; - relatedTarget: EventTarget; - screenX: number; - screenY: number; - shiftKey: boolean; - } - - interface TouchEvent extends SyntheticEvent { - altKey: boolean; - changedTouches: TouchList; - ctrlKey: boolean; - getModifierState(key: string): boolean; - metaKey: boolean; - shiftKey: boolean; - targetTouches: TouchList; - touches: TouchList; - } - - interface UIEvent extends SyntheticEvent { - detail: number; - view: AbstractView; - } - - interface WheelEvent extends SyntheticEvent { - deltaMode: number; - deltaX: number; - deltaY: number; - deltaZ: number; - } - - // - // Event Handler Types - // ---------------------------------------------------------------------- - - interface EventHandler { - (event: E): void; - } - - interface DragEventHandler extends EventHandler {} - interface ClipboardEventHandler extends EventHandler {} - interface KeyboardEventHandler extends EventHandler {} - interface FocusEventHandler extends EventHandler {} - interface FormEventHandler extends EventHandler {} - interface MouseEventHandler extends EventHandler {} - interface TouchEventHandler extends EventHandler {} - interface UIEventHandler extends EventHandler {} - interface WheelEventHandler extends EventHandler {} - - // - // Props / DOM Attributes - // ---------------------------------------------------------------------- - - interface Props { - children?: ReactNode; - key?: string | number; - ref?: string | ((component: T) => any); - } - - interface DOMAttributes extends Props> { - onCopy?: ClipboardEventHandler; - onCut?: ClipboardEventHandler; - onPaste?: ClipboardEventHandler; - onKeyDown?: KeyboardEventHandler; - onKeyPress?: KeyboardEventHandler; - onKeyUp?: KeyboardEventHandler; - onFocus?: FocusEventHandler; - onBlur?: FocusEventHandler; - onChange?: FormEventHandler; - onInput?: FormEventHandler; - onSubmit?: FormEventHandler; - onClick?: MouseEventHandler; - onDoubleClick?: MouseEventHandler; - onDrag?: DragEventHandler; - onDragEnd?: DragEventHandler; - onDragEnter?: DragEventHandler; - onDragExit?: DragEventHandler; - onDragLeave?: DragEventHandler; - onDragOver?: DragEventHandler; - onDragStart?: DragEventHandler; - onDrop?: DragEventHandler; - onMouseDown?: MouseEventHandler; - onMouseEnter?: MouseEventHandler; - onMouseLeave?: MouseEventHandler; - onMouseMove?: MouseEventHandler; - onMouseOut?: MouseEventHandler; - onMouseOver?: MouseEventHandler; - onMouseUp?: MouseEventHandler; - onTouchCancel?: TouchEventHandler; - onTouchEnd?: TouchEventHandler; - onTouchMove?: TouchEventHandler; - onTouchStart?: TouchEventHandler; - onScroll?: UIEventHandler; - onWheel?: WheelEventHandler; - - dangerouslySetInnerHTML?: { - __html: string; - }; - } - - // This interface is not complete. Only properties accepting - // unitless numbers are listed here (see CSSProperty.js in React) - interface CSSProperties { - boxFlex?: number; - boxFlexGroup?: number; - columnCount?: number; - flex?: number | string; - flexGrow?: number; - flexShrink?: number; - fontWeight?: number | string; - lineClamp?: number; - lineHeight?: number | string; - opacity?: number; - order?: number; - orphans?: number; - widows?: number; - zIndex?: number; - zoom?: number; - - // SVG-related properties - fillOpacity?: number; - strokeOpacity?: number; - strokeWidth?: number; - } - - interface HTMLAttributes extends DOMAttributes { - ref?: string | ((component: HTMLComponent) => void); - - accept?: string; - acceptCharset?: string; - accessKey?: string; - action?: string; - allowFullScreen?: boolean; - allowTransparency?: boolean; - alt?: string; - async?: boolean; - autoComplete?: boolean; - autoFocus?: boolean; - autoPlay?: boolean; - cellPadding?: number | string; - cellSpacing?: number | string; - charSet?: string; - checked?: boolean; - classID?: string; - className?: string; - cols?: number; - colSpan?: number; - content?: string; - contentEditable?: boolean; - contextMenu?: string; - controls?: any; - coords?: string; - crossOrigin?: string; - data?: string; - dateTime?: string; - defer?: boolean; - dir?: string; - disabled?: boolean; - download?: any; - draggable?: boolean; - encType?: string; - form?: string; - formAction?: string; - formEncType?: string; - formMethod?: string; - formNoValidate?: boolean; - formTarget?: string; - frameBorder?: number | string; - headers?: string; - height?: number | string; - hidden?: boolean; - high?: number; - href?: string; - hrefLang?: string; - htmlFor?: string; - httpEquiv?: string; - icon?: string; - id?: string; - label?: string; - lang?: string; - list?: string; - loop?: boolean; - low?: number; - manifest?: string; - marginHeight?: number; - marginWidth?: number; - max?: number | string; - maxLength?: number; - media?: string; - mediaGroup?: string; - method?: string; - min?: number | string; - multiple?: boolean; - muted?: boolean; - name?: string; - noValidate?: boolean; - open?: boolean; - optimum?: number; - pattern?: string; - placeholder?: string; - poster?: string; - preload?: string; - radioGroup?: string; - readOnly?: boolean; - rel?: string; - required?: boolean; - role?: string; - rows?: number; - rowSpan?: number; - sandbox?: string; - scope?: string; - scoped?: boolean; - scrolling?: string; - seamless?: boolean; - selected?: boolean; - shape?: string; - size?: number; - sizes?: string; - span?: number; - spellCheck?: boolean; - src?: string; - srcDoc?: string; - srcSet?: string; - start?: number; - step?: number | string; - style?: CSSProperties; - tabIndex?: number; - target?: string; - title?: string; - type?: string; - useMap?: string; - value?: string; - width?: number | string; - wmode?: string; - - // Non-standard Attributes - autoCapitalize?: boolean; - autoCorrect?: boolean; - property?: string; - itemProp?: string; - itemScope?: boolean; - itemType?: string; - unselectable?: boolean; - } - - interface SVGElementAttributes extends HTMLAttributes { - viewBox?: string; - preserveAspectRatio?: string; - } - - interface SVGAttributes extends DOMAttributes { - ref?: string | ((component: SVGComponent) => void); - - cx?: number | string; - cy?: number | string; - d?: string; - dx?: number | string; - dy?: number | string; - fill?: string; - fillOpacity?: number | string; - fontFamily?: string; - fontSize?: number | string; - fx?: number | string; - fy?: number | string; - gradientTransform?: string; - gradientUnits?: string; - markerEnd?: string; - markerMid?: string; - markerStart?: string; - offset?: number | string; - opacity?: number | string; - patternContentUnits?: string; - patternUnits?: string; - points?: string; - preserveAspectRatio?: string; - r?: number | string; - rx?: number | string; - ry?: number | string; - spreadMethod?: string; - stopColor?: string; - stopOpacity?: number | string; - stroke?: string; - strokeDasharray?: string; - strokeLinecap?: string; - strokeOpacity?: number | string; - strokeWidth?: number | string; - textAnchor?: string; - transform?: string; - version?: string; - viewBox?: string; - x1?: number | string; - x2?: number | string; - x?: number | string; - y1?: number | string; - y2?: number | string - y?: number | string; - } - - // - // React.DOM - // ---------------------------------------------------------------------- - - interface ReactDOM { - // HTML - a: HTMLFactory; - abbr: HTMLFactory; - address: HTMLFactory; - area: HTMLFactory; - article: HTMLFactory; - aside: HTMLFactory; - audio: HTMLFactory; - b: HTMLFactory; - base: HTMLFactory; - bdi: HTMLFactory; - bdo: HTMLFactory; - big: HTMLFactory; - blockquote: HTMLFactory; - body: HTMLFactory; - br: HTMLFactory; - button: HTMLFactory; - canvas: HTMLFactory; - caption: HTMLFactory; - cite: HTMLFactory; - code: HTMLFactory; - col: HTMLFactory; - colgroup: HTMLFactory; - data: HTMLFactory; - datalist: HTMLFactory; - dd: HTMLFactory; - del: HTMLFactory; - details: HTMLFactory; - dfn: HTMLFactory; - dialog: HTMLFactory; - div: HTMLFactory; - dl: HTMLFactory; - dt: HTMLFactory; - em: HTMLFactory; - embed: HTMLFactory; - fieldset: HTMLFactory; - figcaption: HTMLFactory; - figure: HTMLFactory; - footer: HTMLFactory; - form: HTMLFactory; - h1: HTMLFactory; - h2: HTMLFactory; - h3: HTMLFactory; - h4: HTMLFactory; - h5: HTMLFactory; - h6: HTMLFactory; - head: HTMLFactory; - header: HTMLFactory; - hr: HTMLFactory; - html: HTMLFactory; - i: HTMLFactory; - iframe: HTMLFactory; - img: HTMLFactory; - input: HTMLFactory; - ins: HTMLFactory; - kbd: HTMLFactory; - keygen: HTMLFactory; - label: HTMLFactory; - legend: HTMLFactory; - li: HTMLFactory; - link: HTMLFactory; - main: HTMLFactory; - map: HTMLFactory; - mark: HTMLFactory; - menu: HTMLFactory; - menuitem: HTMLFactory; - meta: HTMLFactory; - meter: HTMLFactory; - nav: HTMLFactory; - noscript: HTMLFactory; - object: HTMLFactory; - ol: HTMLFactory; - optgroup: HTMLFactory; - option: HTMLFactory; - output: HTMLFactory; - p: HTMLFactory; - param: HTMLFactory; - picture: HTMLFactory; - pre: HTMLFactory; - progress: HTMLFactory; - q: HTMLFactory; - rp: HTMLFactory; - rt: HTMLFactory; - ruby: HTMLFactory; - s: HTMLFactory; - samp: HTMLFactory; - script: HTMLFactory; - section: HTMLFactory; - select: HTMLFactory; - small: HTMLFactory; - source: HTMLFactory; - span: HTMLFactory; - strong: HTMLFactory; - style: HTMLFactory; - sub: HTMLFactory; - summary: HTMLFactory; - sup: HTMLFactory; - table: HTMLFactory; - tbody: HTMLFactory; - td: HTMLFactory; - textarea: HTMLFactory; - tfoot: HTMLFactory; - th: HTMLFactory; - thead: HTMLFactory; - time: HTMLFactory; - title: HTMLFactory; - tr: HTMLFactory; - track: HTMLFactory; - u: HTMLFactory; - ul: HTMLFactory; - "var": HTMLFactory; - video: HTMLFactory; - wbr: HTMLFactory; - - // SVG - circle: SVGFactory; - defs: SVGFactory; - ellipse: SVGFactory; - g: SVGFactory; - line: SVGFactory; - linearGradient: SVGFactory; - mask: SVGFactory; - path: SVGFactory; - pattern: SVGFactory; - polygon: SVGFactory; - polyline: SVGFactory; - radialGradient: SVGFactory; - rect: SVGFactory; - stop: SVGFactory; - svg: SVGFactory; - text: SVGFactory; - tspan: SVGFactory; - } - - // - // React.PropTypes - // ---------------------------------------------------------------------- - - interface Validator { - (object: T, key: string, componentName: string): Error; - } - - interface Requireable extends Validator { - isRequired: Validator; - } - - interface ValidationMap { - [key: string]: Validator; - } - - interface ReactPropTypes { - any: Requireable; - array: Requireable; - bool: Requireable; - func: Requireable; - number: Requireable; - object: Requireable; - string: Requireable; - node: Requireable; - element: Requireable; - instanceOf(expectedClass: {}): Requireable; - oneOf(types: any[]): Requireable; - oneOfType(types: Validator[]): Requireable; - arrayOf(type: Validator): Requireable; - objectOf(type: Validator): Requireable; - shape(type: ValidationMap): Requireable; - } - - // - // React.Children - // ---------------------------------------------------------------------- - - interface ReactChildren { - map(children: ReactNode, fn: (child: ReactChild) => T): { [key:string]: T }; - forEach(children: ReactNode, fn: (child: ReactChild) => any): void; - count(children: ReactNode): number; - only(children: ReactNode): ReactChild; - } - - // - // Browser Interfaces - // https://github.com/nikeee/2048-typescript/blob/master/2048/js/touch.d.ts - // ---------------------------------------------------------------------- - - interface AbstractView { - styleMedia: StyleMedia; - document: Document; - } - - interface Touch { - identifier: number; - target: EventTarget; - screenX: number; - screenY: number; - clientX: number; - clientY: number; - pageX: number; - pageY: number; - } - - interface TouchList { - [index: number]: Touch; - length: number; - item(index: number): Touch; - identifiedTouch(identifier: number): Touch; - } -} - -declare module "react" { - export = React; -} diff --git a/lib/typings/space-pen/space-pen.d.ts b/lib/typings/space-pen/space-pen.d.ts deleted file mode 100644 index eb884e289..000000000 --- a/lib/typings/space-pen/space-pen.d.ts +++ /dev/null @@ -1,625 +0,0 @@ -// Type definitions for SpacePen -// Project: https://github.com/atom/space-pen -// Definitions by: vvakame -// Definitions: https://github.com/borisyankov/DefinitelyTyped - -/// - -// http://atom.github.io/space-pen/ - -interface JQuery { - view():any; - views():any[]; -} - -interface JQuery { - scrollBottom():number; - scrollBottom(newValue:number):JQuery; - scrollDown():JQuery; - scrollUp():JQuery; - scrollToTop():JQuery; - scrollToBottom():JQuery; - scrollRight():number; - scrollRight(newValue:number):JQuery; - pageUp():JQuery; - pageDown():JQuery; - isOnDom():boolean; - isVisible():boolean; - isHidden():boolean; - isDisabled():boolean; - enable():JQuery; - disable():JQuery; - insertAt(index:number, element:any):JQuery; - removeAt(index:number):JQuery; - indexOf(child:any):any; - containsElement(element:any):boolean; - preempt(eventName:any, handler:Function):any; - handlers(eventName:any):any; - hasParent():boolean; - hasFocus():boolean; - flashError():number; - trueHeight():any; - trueWidth():any; - document(eventName:any, docString:string):any; - events():any; - command(eventName:any, handler:any):any; - command(eventName:any, selector:any, handler:any):any; - command(eventName:any, selector:any, options:any, handler:any):any; - iconSize(size:number):void; - intValue():number; -} - -declare class View /* implements JQuery */ { - - static builderStack:Builder[]; - - static subview(name:any, view:any):void; - - static text(str:string):void; - - static tag(tagName:any, ...args:any[]):void; - - static raw(str:string):void; - - static pushBuilder():void; - - static popBuilder():Builder; - - static buildHtml(fn:()=>void):string[]; - - static render(fn:()=>void):JQuery; - - // please override this method! - static content(...args:any[]):void; - - // tag start - static a(...args:any[]):void; - - static abbr(...args:any[]):void; - - static address(...args:any[]):void; - - static article(...args:any[]):void; - - static aside(...args:any[]):void; - - static audio(...args:any[]):void; - - static b(...args:any[]):void; - - static bdi(...args:any[]):void; - - static bdo(...args:any[]):void; - - static blockquote(...args:any[]):void; - - static body(...args:any[]):void; - - static button(...args:any[]):void; - - static canvas(...args:any[]):void; - - static caption(...args:any[]):void; - - static cite(...args:any[]):void; - - static code(...args:any[]):void; - - static colgroup(...args:any[]):void; - - static datalist(...args:any[]):void; - - static dd(...args:any[]):void; - - static del(...args:any[]):void; - - static details(...args:any[]):void; - - static dfn(...args:any[]):void; - - static div(...args:any[]):void; - - static dl(...args:any[]):void; - - static dt(...args:any[]):void; - - static em(...args:any[]):void; - - static fieldset(...args:any[]):void; - - static figcaption(...args:any[]):void; - - static figure(...args:any[]):void; - - static footer(...args:any[]):void; - - static form(...args:any[]):void; - - static h1(...args:any[]):void; - - static h2(...args:any[]):void; - - static h3(...args:any[]):void; - - static h4(...args:any[]):void; - - static h5(...args:any[]):void; - - static h6(...args:any[]):void; - - static head(...args:any[]):void; - - static header(...args:any[]):void; - - static hgroup(...args:any[]):void; - - static html(...args:any[]):void; - - static i(...args:any[]):void; - - static iframe(...args:any[]):void; - - static ins(...args:any[]):void; - - static kbd(...args:any[]):void; - - static label(...args:any[]):void; - - static legend(...args:any[]):void; - - static li(...args:any[]):void; - - static map(...args:any[]):void; - - static mark(...args:any[]):void; - - static menu(...args:any[]):void; - - static meter(...args:any[]):void; - - static nav(...args:any[]):void; - - static noscript(...args:any[]):void; - - static object(...args:any[]):void; - - static ol(...args:any[]):void; - - static optgroup(...args:any[]):void; - - static option(...args:any[]):void; - - static output(...args:any[]):void; - - static p(...args:any[]):void; - - static pre(...args:any[]):void; - - static progress(...args:any[]):void; - - static q(...args:any[]):void; - - static rp(...args:any[]):void; - - static rt(...args:any[]):void; - - static ruby(...args:any[]):void; - - static s(...args:any[]):void; - - static samp(...args:any[]):void; - - static script(...args:any[]):void; - - static section(...args:any[]):void; - - static select(...args:any[]):void; - - static small(...args:any[]):void; - - static span(...args:any[]):void; - - static strong(...args:any[]):void; - - static style(...args:any[]):void; - - static sub(...args:any[]):void; - - static summary(...args:any[]):void; - - static sup(...args:any[]):void; - - static table(...args:any[]):void; - - static tbody(...args:any[]):void; - - static td(...args:any[]):void; - - static textarea(...args:any[]):void; - - static tfoot(...args:any[]):void; - - static th(...args:any[]):void; - - static thead(...args:any[]):void; - - static time(...args:any[]):void; - - static title(...args:any[]):void; - - static tr(...args:any[]):void; - - static u(...args:any[]):void; - - static ul(...args:any[]):void; - - static video(...args:any[]):void; - - static area(...args:any[]):void; - - static base(...args:any[]):void; - - static br(...args:any[]):void; - - static col(...args:any[]):void; - - static command(...args:any[]):void; - - static embed(...args:any[]):void; - - static hr(...args:any[]):void; - - static img(...args:any[]):void; - - static input(...args:any[]):void; - - static keygen(...args:any[]):void; - - static link(...args:any[]):void; - - static meta(...args:any[]):void; - - static param(...args:any[]):void; - - static source(...args:any[]):void; - - static track(...args:any[]):void; - - static wbrk(...args:any[]):void; - - // tag end - - initialize(view:View, args:any):void; - - constructor(...args:any[]); - - buildHtml(params:any):any; - - wireOutlets(view:View):void; - - bindEventHandlers(view:View):void; - - pushStack(elems:any):any; - - end():any; - - command(commandName:any, selector:any, options:any, handler:any):any; - - preempt(eventName:any, handler:any):any; -} - -declare class Builder { - document:any[]; - postProcessingSteps:any[]; - - buildHtml():any[]; - - tag(name:string, ...args:any[]):void; - - openTag(name:string, attributes:any):void; - - closeTag(name:string):void; - - text(str:string):void; - - raw(str:string):void; - - subview(outletName:any, subview:View):void; - - extractOptions(args:any):any; -} - -declare module "space-pen" { - - // copy & paste start - class View /* implements JQueryStatic */ { - - static builderStack:Builder[]; - - static subview(name:any, view:any):void; - - static text(str:string):void; - - static tag(tagName:any, ...args:any[]):void; - - static raw(str:string):void; - - static pushBuilder():void; - - static popBuilder():Builder; - - static buildHtml(fn:()=>void):string[]; - - static render(fn:()=>void):JQuery; - - // please override this method! - static content(...args:any[]):void; - - // tag start - static a(...args:any[]):any; - - static abbr(...args:any[]):any; - - static address(...args:any[]):any; - - static article(...args:any[]):any; - - static aside(...args:any[]):any; - - static audio(...args:any[]):any; - - static b(...args:any[]):any; - - static bdi(...args:any[]):any; - - static bdo(...args:any[]):any; - - static blockquote(...args:any[]):any; - - static body(...args:any[]):any; - - static button(...args:any[]):any; - - static canvas(...args:any[]):any; - - static caption(...args:any[]):any; - - static cite(...args:any[]):any; - - static code(...args:any[]):any; - - static colgroup(...args:any[]):any; - - static datalist(...args:any[]):any; - - static dd(...args:any[]):any; - - static del(...args:any[]):any; - - static details(...args:any[]):any; - - static dfn(...args:any[]):any; - - static div(...args:any[]):any; - - static dl(...args:any[]):any; - - static dt(...args:any[]):any; - - static em(...args:any[]):any; - - static fieldset(...args:any[]):any; - - static figcaption(...args:any[]):any; - - static figure(...args:any[]):any; - - static footer(...args:any[]):any; - - static form(...args:any[]):any; - - static h1(...args:any[]):any; - - static h2(...args:any[]):any; - - static h3(...args:any[]):any; - - static h4(...args:any[]):any; - - static h5(...args:any[]):any; - - static h6(...args:any[]):any; - - static head(...args:any[]):any; - - static header(...args:any[]):any; - - static hgroup(...args:any[]):any; - - static html(...args:any[]):any; - - static i(...args:any[]):any; - - static iframe(...args:any[]):any; - - static ins(...args:any[]):any; - - static kbd(...args:any[]):any; - - static label(...args:any[]):any; - - static legend(...args:any[]):any; - - static li(...args:any[]):any; - - static map(...args:any[]):any; - - static mark(...args:any[]):any; - - static menu(...args:any[]):any; - - static meter(...args:any[]):any; - - static nav(...args:any[]):any; - - static noscript(...args:any[]):any; - - static object(...args:any[]):any; - - static ol(...args:any[]):any; - - static optgroup(...args:any[]):any; - - static option(...args:any[]):any; - - static output(...args:any[]):any; - - static p(...args:any[]):any; - - static pre(...args:any[]):any; - - static progress(...args:any[]):any; - - static q(...args:any[]):any; - - static rp(...args:any[]):any; - - static rt(...args:any[]):any; - - static ruby(...args:any[]):any; - - static s(...args:any[]):any; - - static samp(...args:any[]):any; - - static script(...args:any[]):any; - - static section(...args:any[]):any; - - static select(...args:any[]):any; - - static small(...args:any[]):any; - - static span(...args:any[]):any; - - static strong(...args:any[]):any; - - static style(...args:any[]):any; - - static sub(...args:any[]):any; - - static summary(...args:any[]):any; - - static sup(...args:any[]):any; - - static table(...args:any[]):any; - - static tbody(...args:any[]):any; - - static td(...args:any[]):any; - - static textarea(...args:any[]):any; - - static tfoot(...args:any[]):any; - - static th(...args:any[]):any; - - static thead(...args:any[]):any; - - static time(...args:any[]):any; - - static title(...args:any[]):any; - - static tr(...args:any[]):any; - - static u(...args:any[]):any; - - static ul(...args:any[]):any; - - static video(...args:any[]):any; - - static area(...args:any[]):any; - - static base(...args:any[]):any; - - static br(...args:any[]):any; - - static col(...args:any[]):any; - - static command(...args:any[]):any; - - static embed(...args:any[]):any; - - static hr(...args:any[]):any; - - static img(...args:any[]):any; - - static input(...args:any[]):any; - - static keygen(...args:any[]):any; - - static link(...args:any[]):any; - - static meta(...args:any[]):any; - - static param(...args:any[]):any; - - static source(...args:any[]):any; - - static track(...args:any[]):any; - - static wbrk(...args:any[]):any; - - // tag end - - initialize(view:View, args:any):void; - - constructor(...args:any[]); - - buildHtml(params:any):any; - - wireOutlets(view:View):void; - - bindEventHandlers(view:View):void; - - pushStack(elems:any):any; - - end():any; - - command(eventName:string, handler:any):any; - - command(eventName:string, selector:any, handler:any):any; - - command(eventName:string, selector:any, options:any, handler:any):any; - - preempt(eventName:any, handler:any):any; - } - - class Builder { - document:any[]; - postProcessingSteps:any[]; - - buildHtml():any[]; - - tag(name:string, ...args:any[]):void; - - openTag(name:string, attributes:any):void; - - closeTag(name:string):void; - - text(str:string):void; - - raw(str:string):void; - - subview(outletName:any, subview:View):void; - - extractOptions(args:any):any; - } - // copy & paste end - - - var jQuery:JQueryStatic; - var $:JQueryStatic; - var $$:(fn:Function)=>JQuery; // same type as View.render's return type. - var $$$:(fn:Function)=>any; // same type as View.buildHtml's return type's [0]. -} diff --git a/lib/typings/status-bar/status-bar.d.ts b/lib/typings/status-bar/status-bar.d.ts deleted file mode 100644 index 6c6788720..000000000 --- a/lib/typings/status-bar/status-bar.d.ts +++ /dev/null @@ -1,32 +0,0 @@ -// Type definitions for status-bar -// Project: https://github.com/atom/status-bar -// Definitions by: vvakame -// Definitions: https://github.com/borisyankov/DefinitelyTyped - -/// -/// - -declare module StatusBar { - interface IStatusBarViewStatic { - content():any; - - new(...args:any[]):IStatusBarView; - } - - interface IStatusBarView extends View { - - initialize():any; - attach():any; - destroy():any; - appendLeft(view:View):any; - prependLeft(view:View):any; - appendRight(view:View):any; - prependRight(view:View):any; - getActiveBuffer():TextBuffer.ITextBuffer; - getActiveItem():any; - storeActiveBuffer():TextBuffer.ITextBuffer; - subscribeToBuffer(event:string, callback:Function):any; - subscribeAllToBuffer():any[]; - unsubscribeAllFromBuffer():any[]; - } -} diff --git a/lib/typings/status_bar.d.ts b/lib/typings/status_bar.d.ts new file mode 100644 index 000000000..301e4ec2e --- /dev/null +++ b/lib/typings/status_bar.d.ts @@ -0,0 +1,17 @@ +export interface NewTile { + item: any + priority: number +} + +export interface Tile { + getPriority(): number + getItem(): any + destroy() +} + +export interface StatusBar { + addLeftTile(tile: NewTile) + addRightTile(tile: NewTile) + getLeftTiles(): Tile[] + getRightTiles(): Tile[] +} diff --git a/lib/typings/text-buffer/text-buffer.d.ts b/lib/typings/text-buffer/text-buffer.d.ts deleted file mode 100644 index 2aed41bc8..000000000 --- a/lib/typings/text-buffer/text-buffer.d.ts +++ /dev/null @@ -1,305 +0,0 @@ -// Type definitions for text-buffer -// Project: https://github.com/atom/text-buffer -// Definitions by: vvakame -// Definitions: https://github.com/borisyankov/DefinitelyTyped - -/// -/// -/// - - -declare module TextBuffer { - - interface IPointStatic { - new (row?:number, column?:number):IPoint; - - fromObject(point:IPoint, copy?:boolean):IPoint; - fromObject(object:number[]):IPoint; - fromObject(object:{row:number; column:number;}):IPoint; - - min(point1:IPoint, point2:IPoint):IPoint; - min(point1:number[], point2:IPoint):IPoint; - min(point1:{row:number; column:number;}, point2:IPoint):IPoint; - - min(point1:IPoint, point2:number[]):IPoint; - min(point1:number[], point2:number[]):IPoint; - min(point1:{row:number; column:number;}, point2:number[]):IPoint; - - min(point1:IPoint, point2:{row:number; column:number;}):IPoint; - min(point1:number[], point2:{row:number; column:number;}):IPoint; - min(point1:{row:number; column:number;}, point2:{row:number; column:number;}):IPoint; - } - - interface IPoint { - constructor: IPointStatic; - - row:number; - column:number; - - copy():IPoint; - freeze():IPoint; - - translate(delta:IPoint):IPoint; - translate(delta:number[]):IPoint; - translate(delta:{row:number; column:number;}):IPoint; - - add(other:IPoint):IPoint; - add(other:number[]):IPoint; - add(other:{row:number; column:number;}):IPoint; - - splitAt(column:number):IPoint[]; - compare(other:IPoint):number; - isEqual(other:IPoint):boolean; - isLessThan(other:IPoint):boolean; - isLessThanOrEqual(other:IPoint):boolean; - isGreaterThan(other:IPoint):boolean; - isGreaterThanOrEqual(other:IPoint):boolean; - toArray():number[]; - serialize():number[]; - } - - interface IRangeStatic { - deserialize(array:IPoint[]):IRange; - - fromObject(object:IPoint[]):IRange; - - fromObject(object:IRange, copy?:boolean):IRange; - - fromObject(object:{start: IPoint; end: IPoint}):IRange; - fromObject(object:{start: number[]; end: IPoint}):IRange; - fromObject(object:{start: {row:number; column:number;}; end: IPoint}):IRange; - - fromObject(object:{start: IPoint; end: number[]}):IRange; - fromObject(object:{start: number[]; end: number[]}):IRange; - fromObject(object:{start: {row:number; column:number;}; end: number[]}):IRange; - - fromObject(object:{start: IPoint; end: {row:number; column:number;}}):IRange; - fromObject(object:{start: number[]; end: {row:number; column:number;}}):IRange; - fromObject(object:{start: {row:number; column:number;}; end: {row:number; column:number;}}):IRange; - - fromText(point:IPoint, text:string):IRange; - fromText(point:number[], text:string):IRange; - fromText(point:{row:number; column:number;}, text:string):IRange; - fromText(text:string):IRange; - - fromPointWithDelta(startPoint:IPoint, rowDelta:number, columnDelta:number):IRange; - fromPointWithDelta(startPoint:number[], rowDelta:number, columnDelta:number):IRange; - fromPointWithDelta(startPoint:{row:number; column:number;}, rowDelta:number, columnDelta:number):IRange; - - new(point1:IPoint, point2:IPoint):IRange; - new(point1:number[], point2:IPoint):IRange; - new(point1:{row:number; column:number;}, point2:IPoint):IRange; - - new(point1:IPoint, point2:number[]):IRange; - new(point1:number[], point2:number[]):IRange; - new(point1:{row:number; column:number;}, point2:number[]):IRange; - - new(point1:IPoint, point2:{row:number; column:number;}):IRange; - new(point1:number[], point2:{row:number; column:number;}):IRange; - new(point1:{row:number; column:number;}, point2:{row:number; column:number;}):IRange; - } - - interface IRange { - constructor:IRangeStatic; - - start: IPoint; - end: IPoint; - - serialize():number[][]; - copy():IRange; - freeze():IRange; - isEqual(other:IRange):boolean; - isEqual(other:IPoint[]):boolean; - - compare(object:IPoint[]):number; - - compare(object:{start: IPoint; end: IPoint}):number; - compare(object:{start: number[]; end: IPoint}):number; - compare(object:{start: {row:number; column:number;}; end: IPoint}):number; - - compare(object:{start: IPoint; end: number[]}):number; - compare(object:{start: number[]; end: number[]}):number; - compare(object:{start: {row:number; column:number;}; end: number[]}):number; - - compare(object:{start: IPoint; end: {row:number; column:number;}}):number; - compare(object:{start: number[]; end: {row:number; column:number;}}):number; - compare(object:{start: {row:number; column:number;}; end: {row:number; column:number;}}):number; - - isSingleLine():boolean; - coversSameRows(other:IRange):boolean; - - add(object:IPoint[]):IRange; - - add(object:{start: IPoint; end: IPoint}):IRange; - add(object:{start: number[]; end: IPoint}):IRange; - add(object:{start: {row:number; column:number;}; end: IPoint}):IRange; - - add(object:{start: IPoint; end: number[]}):IRange; - add(object:{start: number[]; end: number[]}):IRange; - add(object:{start: {row:number; column:number;}; end: number[]}):IRange; - - add(object:{start: IPoint; end: {row:number; column:number;}}):IRange; - add(object:{start: number[]; end: {row:number; column:number;}}):IRange; - add(object:{start: {row:number; column:number;}; end: {row:number; column:number;}}):IRange; - - translate(startPoint:IPoint, endPoint:IPoint):IRange; - translate(startPoint:IPoint):IRange; - - intersectsWith(otherRange:IRange):boolean; - containsRange(otherRange:IRange, exclusive:boolean):boolean; - - containsPoint(point:IPoint, exclusive:boolean):boolean; - containsPoint(point:number[], exclusive:boolean):boolean; - containsPoint(point:{row:number; column:number;}, exclusive:boolean):boolean; - - intersectsRow(row:number):boolean; - intersectsRowRange(startRow:number, endRow:number):boolean; - union(otherRange:IRange):IRange; - isEmpty():boolean; - toDelta():IPoint; - getRowCount():number; - getRows():number[]; - } - - interface IHistory { - // TBD - } - - interface IMarkerManager { - // TBD - } - - interface IMarker { - // TBD - } - - interface IBufferPatch { - // TBD - } - - interface ITextBufferStatic { - Point: IPointStatic; - Range: IRangeStatic; - newlineRegex:any; - - new (text:string): ITextBuffer; - new (params:any): ITextBuffer; - } - - interface ITextBuffer extends Emissary.IEmitter, Emissary.ISubscriber { - // Delegator.includeInto(TextBuffer); - // Serializable.includeInto(TextBuffer); - - cachedText:string; - stoppedChangingDelay:number; - stoppedChangingTimeout:any; - cachedDiskContents:string; - conflict:boolean; - file:any; // pathwatcher.IFile - refcount:number; - - lines:string[]; - lineEndings:string[]; - offsetIndex:any; // span-skip-list.SpanSkipList - history:IHistory; - markers:IMarkerManager; - loaded:boolean; - digestWhenLastPersisted:string; - modifiedWhenLastPersisted:boolean; - useSerializedText:boolean; - - deserializeParams(params:any):any; - serializeParams():any; - - getText():string; - getLines():string; - isEmpty():boolean; - getLineCount():number; - getLastRow():number; - lineForRow(row:number):string; - getLastLine():string; - lineEndingForRow(row:number):string; - lineLengthForRow(row:number):number; - setText(text:string):IRange; - setTextViaDiff(text:any):any[]; - setTextInRange(range:IRange, text:string, normalizeLineEndings?:boolean):IRange; - setTextInRange(range:[[number,number],[number,number]], text:string, config?:{normalizeLineEndings?:boolean}):IRange; - insert(position:IPoint, text:string, normalizeLineEndings?:boolean):IRange; - append(text:string, normalizeLineEndings?:boolean):IRange; - delete(range:IRange):IRange; - deleteRow(row:number):IRange; - deleteRows(startRow:number, endRow:number):IRange; - buildPatch(oldRange:IRange, newText:string, normalizeLineEndings?:boolean):IBufferPatch; - applyPatch(patch:IBufferPatch):any; - getTextInRange(range:IRange):string; - clipRange(range:IRange):IRange; - clipPosition(position:IPoint):IPoint; - getFirstPosition():IPoint; - getEndPosition():IPoint; - getRange():IRange; - rangeForRow(row:number, includeNewline?:boolean):IRange; - characterIndexForPosition(position:IPoint):number; - characterIndexForPosition(position:[number,number]):number; - positionForCharacterIndex(offset:number):IPoint; - getMaxCharacterIndex():number; - loadSync():ITextBuffer; - load():Q.IPromise; - finishLoading():ITextBuffer; - handleTextChange(event:any):any; - destroy():any; - isAlive():boolean; - isDestroyed():boolean; - isRetained():boolean; - retain():ITextBuffer; - release():ITextBuffer; - subscribeToFile():any; - hasMultipleEditors():boolean; - reload():any; - updateCachedDiskContentsSync():string; - updateCachedDiskContents():Q.IPromise; - getBaseName():string; - getPath():string; - getUri():string; - setPath(filePath:string):any; - save():void; - saveAs(filePath:string):any; - isModified():boolean; - isInConflict():boolean; - destroyMarker(id:any):any; - matchesInCharacterRange(regex:any, startIndex:any, endIndex:any):any[]; - scan(regex:any, iterator:any):any; - backwardsScan(regex:any, iterator:any):any; - replace(regex:any, replacementText:any):any; - scanInRange(regex:any, range:any, iterator:any, reverse:any):any; - backwardsScanInRange(regex:any, range:any, iterator:any):any; - isRowBlank(row:number):boolean; - previousNonBlankRow(startRow:number):number; - nextNonBlankRow(startRow:number):number; - usesSoftTabs():boolean; - cancelStoppedChangingTimeout():any; - scheduleModifiedEvents():any; - emitModifiedStatusChanged(modifiedStatus:any):any; - logLines(start:number, end:number):void; - - // delegate to history property - undo():any; - redo():any; - transact(fn:Function):any; - beginTransaction():any; - commitTransaction():any; - abortTransaction():any; - clearUndoStack():any; - - // delegate to markers property - markRange(range:any, properties:any):any; - markPosition(range:any, properties:any):any; - getMarker(id:number):IMarker; - getMarkers():IMarker[]; - getMarkerCount():number; - } -} - -declare module "text-buffer" { - var _: TextBuffer.ITextBufferStatic; - export = _; -} \ No newline at end of file diff --git a/lib/typings/tsd.d.ts b/lib/typings/tsd.d.ts deleted file mode 100644 index 47917ffd9..000000000 --- a/lib/typings/tsd.d.ts +++ /dev/null @@ -1,14 +0,0 @@ -/// -/// -/// -/// -/// -/// -/// -/// -/// -/// -/// -/// -/// -/// diff --git a/lib/typings/typings.d.ts b/lib/typings/typings.d.ts new file mode 100644 index 000000000..f071b671b --- /dev/null +++ b/lib/typings/typings.d.ts @@ -0,0 +1,23 @@ +interface Window { + atom_typescript_debug: boolean +} + +// escape-html +declare module 'escape-html' { + function escape(html: string): string; + export = escape; +} + +declare module 'atom-space-pen-views' { + import atom = require('atom'); + export class SelectListView extends atom.SelectListView { } + export class ScrollView extends atom.ScrollView { } + export class View extends atom.View { } + export var $: JQueryStatic; +} + +declare module AtomCore { + export interface IEditor { + element: any; + } +} diff --git a/lib/worker/child.ts b/lib/worker/child.ts deleted file mode 100644 index b23edce60..000000000 --- a/lib/worker/child.ts +++ /dev/null @@ -1,25 +0,0 @@ -var typescriptServices = ''; -if (process.argv.length > 2) { - typescriptServices = process.argv[2]; -} -// setup typescript -import {makeTsGlobal} from "../typescript/makeTypeScriptGlobal"; -makeTsGlobal(typescriptServices); -import {setTypescriptServices} from "../main/lang/typescriptServices"; -setTypescriptServices(typescriptServices); - -import workerLib = require('./lib/workerLib'); - - -// Initiate the child logic -var child = new workerLib.Child(); - -/////////////////////////////////////// END INFRASTRUCTURE //////////////////////////////////////////////////// -import * as projectCache from "../main/lang/projectCache"; -// push in child -projectCache.fixChild(child); - - -// Automatically include all functions from "projectService" as a responder -import projectService = require('../main/lang/projectService'); -child.registerAllFunctionsExportedFromAsResponders(projectService); diff --git a/lib/worker/debug.ts b/lib/worker/debug.ts deleted file mode 100644 index 281133b15..000000000 --- a/lib/worker/debug.ts +++ /dev/null @@ -1,5 +0,0 @@ -/** Set this to true if you want to debug all things */ -export var debugAll = false; - -/** Set this to true to run the child code in the UI thread and just debug using the dev tools */ -export var debugSync = false || debugAll; diff --git a/lib/worker/lib/workerLib.ts b/lib/worker/lib/workerLib.ts deleted file mode 100644 index d14d6c1bb..000000000 --- a/lib/worker/lib/workerLib.ts +++ /dev/null @@ -1,338 +0,0 @@ -// This code is designed to be used by both the parent and the child -import childprocess = require('child_process'); -var exec = childprocess.exec; -var spawn = childprocess.spawn; -import path = require('path'); - -// Parent makes queries -// Child responds -export interface Message { - message: string; - id: string; - data?: T; - error?: { - method: string; - message: string; - stack: string; - details: any; - }; - /** Is this message a request or a response */ - request: boolean; -} - -/** Query Response function */ -export interface QRFunction { - (query: Query): Promise; -} - -/** Creates a Guid (UUID v4) */ -function createId(): string { - return 'xxxxxxxx-xxxx-4xxx-yxxx-xxxxxxxxxxxx'.replace(/[xy]/g, function(c) { - var r = Math.random() * 16 | 0, v = c == 'x' ? r : (r & 0x3 | 0x8); - return v.toString(16); - }); -} - -/** Used by parent and child for keepalive */ -var orphanExitCode = 100; - -class RequesterResponder { - - /** Must be implemented in children */ - protected getProcess: { - (): { send?: (message: Message) => any } - } - - ///////////////////////////////// REQUESTOR ///////////////////////// - - private currentListeners: { [message: string]: { [id: string]: PromiseDeferred } } = {}; - - /** Only relevant when we only want the last of this type */ - private currentLastOfType: { - [message: string]: { data: any; defer: PromiseDeferred; } - } = {}; - - private pendingRequests: string[] = []; - public pendingRequestsChanged = (pending: string[]) => null; - - /** process a message from the child */ - protected processResponse(m: any) { - var parsed: Message = m; - - this.pendingRequests.shift(); - this.pendingRequestsChanged(this.pendingRequests); - - if (!parsed.message || !parsed.id) { - console.log('PARENT ERR: Invalid JSON data from child:', m); - } - else if (!this.currentListeners[parsed.message] || !this.currentListeners[parsed.message][parsed.id]) { - console.log('PARENT ERR: No one was listening:', parsed.message, parsed.data); - } - else { // Alright nothing *weird* happened - if (parsed.error) { - this.currentListeners[parsed.message][parsed.id].reject(parsed.error); - console.log(parsed.error); - console.log(parsed.error.stack); - } - else { - this.currentListeners[parsed.message][parsed.id].resolve(parsed.data); - } - delete this.currentListeners[parsed.message][parsed.id]; - - // If there is current last one queued then that needs to be resurrected - if (this.currentLastOfType[parsed.message]) { - let last = this.currentLastOfType[parsed.message]; - delete this.currentLastOfType[parsed.message]; - let lastPromise = this.sendToIpcHeart(last.data, parsed.message); - lastPromise.then((res) => last.defer.resolve(res), (rej) => last.defer.reject(rej)); - } - } - } - - private sendToIpcHeart = (data, message) => { - - // If we don't have a child exit - if (!this.getProcess()) { - console.log('PARENT ERR: no child when you tried to send :', message); - return Promise.reject(new Error("No worker active to recieve message: " + message)); - } - - // Initialize if this is the first call of this type - if (!this.currentListeners[message]) this.currentListeners[message] = {}; - - // Create an id unique to this call and store the defered against it - var id = createId(); - const promise = new Promise((resolve,reject)=>{ - this.currentListeners[message][id] = { resolve, reject, promise }; - }); - - // Send data to worker - this.pendingRequests.push(message); - this.pendingRequestsChanged(this.pendingRequests); - this.getProcess().send({ message: message, id: id, data: data, request: true }); - return promise; - } - - /** - * Takes a sync named function - * and returns a function that will execute this function by name using IPC - * (will only work if the process on the other side has this function as a registered responder) - */ - sendToIpc(func: QRFunction): QRFunction { - var message = func.name; - return (data) => this.sendToIpcHeart(data, message); - } - - /** - * If there are more than one pending then we only want the last one as they come in. - * All others will get the default value - */ - sendToIpcOnlyLast(func: QRFunction, defaultResponse: Response): QRFunction { - return (data) => { - var message = func.name; - - // If we don't have a child exit - if (!this.getProcess()) { - console.log('PARENT ERR: no child when you tried to send :', message); - return Promise.reject(new Error("No worker active to recieve message: " + message)); - } - - // Allow if this is the only call of this type - if (!Object.keys(this.currentListeners[message] || {}).length) { - return this.sendToIpcHeart(data, message); - } - else { - // Note: - // The last needs to continue once the current one finishes - // That is done in our response handler - - - // If there is already something queued as last. - // Then it is no longer last and needs to be fed a default value - if (this.currentLastOfType[message]) { - this.currentLastOfType[message].defer.resolve(defaultResponse); - } - - // this needs to be the new last - const promise = new Promise((resolve,reject)=>{ - this.currentLastOfType[message] = { - data: data, - defer: {promise,resolve,reject} - } - }); - return promise; - } - }; - } - - ////////////////////////////////// RESPONDER //////////////////////// - - private responders: { [message: string]: (query: Query) => Promise } = {}; - - protected processRequest = (m: any) => { - var parsed: Message = m; - if (!parsed.message || !this.responders[parsed.message]) { - // TODO: handle this error scenario. Either the message is invalid or we do not have a registered responder - return; - } - var message = parsed.message; - var responsePromise: Promise; - try { - responsePromise = this.responders[message](parsed.data); - } catch (err) { - responsePromise = Promise.reject({ method: message, message: err.message, stack: err.stack, details: err.details || {} }); - } - - responsePromise - .then((response) => { - this.getProcess().send({ - message: message, - /** Note: to process a request we just pass the id as we recieve it */ - id: parsed.id, - data: response, - error: null, - request: false - }); - }) - .catch((error) => { - this.getProcess().send({ - message: message, - /** Note: to process a request we just pass the id as we recieve it */ - id: parsed.id, - data: null, - error: error, - request: false - }); - }); - } - - private addToResponders(func: (query: Query) => Promise) { - this.responders[func.name] = func; - } - - registerAllFunctionsExportedFromAsResponders(aModule: any) { - Object.keys(aModule) - .filter((funcName) => typeof aModule[funcName] == 'function') - .forEach((funcName) => this.addToResponders(aModule[funcName])); - } -} - -/** The parent */ -export class Parent extends RequesterResponder { - - private child: childprocess.ChildProcess; - private node = process.execPath; - - /** If we get this error then the situation if fairly hopeless */ - private gotENOENTonSpawnNode = false; - protected getProcess = () => this.child; - private stopped = false; - - /** start worker */ - startWorker(childJsPath: string, terminalError: (e: Error) => any, customArguments: string[]) { - try { - /** At least on NixOS, the environment must be preserved for - dynamic libraries to be properly linked. - On Windows/MacOS, it needs to be cleared, cf. atom/atom#2887 */ - var spawnEnv = (process.platform === 'linux') ? Object.create(process.env) : {}; - spawnEnv['ELECTRON_RUN_AS_NODE'] = 1; - this.child = spawn(this.node, [ - // '--debug', // Uncomment if you want to debug the child process - childJsPath - ].concat(customArguments), { - cwd: path.dirname(childJsPath), - env: spawnEnv, - stdio: ['ipc'] - }); - - this.child.on('error', (err) => { - if (err.code === "ENOENT" && err.path === this.node) { - this.gotENOENTonSpawnNode = true; - } - console.log('CHILD ERR ONERROR:', err.message, err.stack, err); - this.child = null; - }); - - this.child.on('message', (message: Message) => { - if (message.request) { - this.processRequest(message); - } - else { - this.processResponse(message); - } - }); - - this.child.stderr.on('data', (err) => { - console.log("CHILD ERR STDERR:", err.toString()); - }); - this.child.on('close', (code) => { - if (this.stopped) { - return; - } - - // Handle process dropping - - // If orphaned then Definitely restart - if (code === orphanExitCode) { - this.startWorker(childJsPath, terminalError, customArguments); - } - // If we got ENOENT. Restarting will not help. - else if (this.gotENOENTonSpawnNode) { - terminalError(new Error('gotENOENTonSpawnNode')); - } - // We haven't found a reson to not start worker yet - else { - console.log("ts worker restarting. Don't know why it stopped with code:", code); - this.startWorker(childJsPath, terminalError, customArguments); - } - }); - } catch (err) { - terminalError(err); - } - } - - /** stop worker */ - stopWorker() { - this.stopped = true; - if (!this.child) return; - try { - this.child.kill('SIGTERM'); - } - catch (ex) { - console.error('failed to kill worker child'); - } - this.child = null; - } -} - -export class Child extends RequesterResponder { - - protected getProcess = () => process; - - constructor() { - super(); - - // Keep alive - this.keepAlive(); - - // Start listening - process.on('message', (message: Message) => { - if (message.request) { - this.processRequest(message); - } - else { - this.processResponse(message); - } - }); - } - - /** keep the child process alive while its connected and die otherwise */ - private keepAlive() { - setInterval(() => { - // We have been orphaned - if (!(process).connected) { - process.exit(orphanExitCode); - } - }, 1000); - } -} diff --git a/lib/worker/parent.ts b/lib/worker/parent.ts deleted file mode 100644 index 0102aded0..000000000 --- a/lib/worker/parent.ts +++ /dev/null @@ -1,106 +0,0 @@ -import {debugSync} from "./debug"; - -import childprocess = require('child_process'); -var exec = childprocess.exec; -var spawn = childprocess.spawn; - -import workerLib = require('./lib/workerLib'); -import tsconfig = require('../main/tsconfig/tsconfig'); -import * as atomConfig from "../main/atom/atomConfig"; - -var parent = new workerLib.Parent(); -import * as mainPanel from "../main/atom/views/mainPanelView"; -parent.pendingRequestsChanged = (pending) => { - // We only start once the panel view is initialized - if (!mainPanel.panelView) return; - - mainPanel.panelView.updatePendingRequests(pending); -}; - -/** The only effect of debug is to really not route stuff to the child */ -if (debugSync) { - parent.sendToIpc = x => x; - parent.sendToIpcOnlyLast = x => x; -} - -export function startWorker() { - if (!debugSync) { - parent.startWorker(__dirname + '/child.js', showError, atomConfig.typescriptServices ? [atomConfig.typescriptServices] : []); - } -} - -export function stopWorker() { - if (!debugSync) { - parent.stopWorker(); - } -} - -function showError(error: Error) { - var message = "Failed to start a child TypeScript worker. Atom-TypeScript is disabled."; - // Sad panda : https://github.com/TypeStrong/atom-typescript/issues/50 - if (process.platform === "win32") { - message = message + " Make sure you have 'node' installed and available in your system path."; - } - atom.notifications.addError(message, { dismissable: true }); - - if (error) { - console.error('Failed to activate ts-worker:', error); - } -} - -/////////////////////////////////////// END INFRASTRUCTURE //////////////////////////////////////////////////// - -/** Doesn't mess with any data. Just shows it nicely in the UI */ -function catchCommonErrors(func: workerLib.QRFunction): workerLib.QRFunction { - return (q) => func(q).catch((err: Error) => { - // Left only as a sample - // We handle these errors elsewhere now - /*if (err.message == tsconfig.errors.GET_PROJECT_JSON_PARSE_FAILED) { - atom.notifications.addError('The tsconfig.json file for this TypeScript file contains invalid JSON'); - }*/ - return Promise.reject(err); - }); -} - -///ts:import=projectService -import projectService = require('../main/lang/projectService'); ///ts:import:generated - -export var echo = catchCommonErrors(parent.sendToIpc(projectService.echo)); -export var quickInfo = catchCommonErrors(parent.sendToIpc(projectService.quickInfo)); -export var build = catchCommonErrors(parent.sendToIpc(projectService.build)); -export var getCompletionsAtPosition = parent.sendToIpcOnlyLast(projectService.getCompletionsAtPosition, { - completions: [], - endsInPunctuation: false -}); -export var emitFile = catchCommonErrors(parent.sendToIpc(projectService.emitFile)); -export var formatDocument = catchCommonErrors(parent.sendToIpc(projectService.formatDocument)); -export var formatDocumentRange = catchCommonErrors(parent.sendToIpc(projectService.formatDocumentRange)); -export var getDefinitionsAtPosition = catchCommonErrors(parent.sendToIpc(projectService.getDefinitionsAtPosition)); -export var updateText = catchCommonErrors(parent.sendToIpc(projectService.updateText)); -export var editText = catchCommonErrors(parent.sendToIpc(projectService.editText)); -export var errorsForFile = catchCommonErrors(parent.sendToIpc(projectService.errorsForFile)); -export var getSignatureHelps = catchCommonErrors(parent.sendToIpc(projectService.getSignatureHelps)); -export var getRenameInfo = catchCommonErrors(parent.sendToIpc(projectService.getRenameInfo)); -export var getRelativePathsInProject = catchCommonErrors(parent.sendToIpc(projectService.getRelativePathsInProject)); -export var debugLanguageServiceHostVersion = parent.sendToIpc(projectService.debugLanguageServiceHostVersion); -export var getProjectFileDetails = parent.sendToIpc(projectService.getProjectFileDetails); -export var getNavigationBarItems = parent.sendToIpc(projectService.getNavigationBarItems); -export var getSemtanticTree = parent.sendToIpc(projectService.getSemtanticTree); -export var getNavigateToItems = parent.sendToIpc(projectService.getNavigateToItems); -export var getReferences = parent.sendToIpc(projectService.getReferences); -export var getAST = parent.sendToIpc(projectService.getAST); -export var getASTFull = parent.sendToIpc(projectService.getASTFull); -export var getDependencies = parent.sendToIpc(projectService.getDependencies); -export var getQuickFixes = parent.sendToIpc(projectService.getQuickFixes); -export var applyQuickFix = parent.sendToIpc(projectService.applyQuickFix); -export var getOutput = parent.sendToIpc(projectService.getOutput); -export var getOutputJs = parent.sendToIpc(projectService.getOutputJs); -export var getOutputJsStatus = parent.sendToIpc(projectService.getOutputJsStatus); -export var softReset = parent.sendToIpc(projectService.softReset); -export var getRenameFilesRefactorings = parent.sendToIpc(projectService.getRenameFilesRefactorings); -export var createProject = parent.sendToIpc(projectService.createProject); -export var toggleBreakpoint = parent.sendToIpc(projectService.toggleBreakpoint); - -// Automatically include all functions from "parentResponses" as responders -import queryParent = require('./queryParent'); -parent.registerAllFunctionsExportedFromAsResponders(queryParent); diff --git a/lib/worker/queryParent.ts b/lib/worker/queryParent.ts deleted file mode 100644 index e9f6d0590..000000000 --- a/lib/worker/queryParent.ts +++ /dev/null @@ -1,125 +0,0 @@ -/// Functions that the parent allows the child to query - -var resolve: typeof Promise.resolve = Promise.resolve.bind(Promise); - -// safe imports -// stuff that exists in both Worker and Parent -import tsconfig = require('../main/tsconfig/tsconfig'); -import project = require('../main/lang/core/project'); - -// UI Imports -import _atomUtils = require('../main/atom/atomUtils'); -var atomUtils: typeof _atomUtils; -import _mainPanelView = require('../main/atom/views/mainPanelView'); -var mainPanelView: typeof _mainPanelView; - -try { - require('atom'); - // We are in a safe context: - atomUtils = require('../main/atom/atomUtils'); - mainPanelView = require('../main/atom/views/mainPanelView'); -} -catch (ex) { - // We just need to type information for this context -} - -// TODO: move into globals -export interface Position { - line: number; - col: number; -} -export interface TSError { - filePath: string; - startPos: Position; - endPos: Position; - message: string; - preview: string; -} - -export function echoNumWithModification(query: { num: number }): Promise<{ num: number }> { - return Promise.resolve({ num: query.num + 10 }); -} - -export function getUpdatedTextForUnsavedEditors(query: {}): Promise<{ editors: { filePath: string; text: string }[] }> { - var editors = atomUtils.getTypeScriptEditorsWithPaths().filter(editor => editor.isModified()); - return resolve({ - editors: editors.map(e=> { - return { filePath: e.getPath(), text: e.getText() } - }) - }); -} - -export function getOpenEditorPaths(query: {}): Promise<{ filePaths: string[] }> { - var paths = atomUtils.getOpenTypeScritEditorsConsistentPaths(); - return resolve({ - filePaths: paths - }); -} - -export function setConfigurationError(query: { projectFilePath: string; error: { message: string; details: any } }): Promise<{}> { - var errors: TSError[] = []; - if (query.error) { - if (query.error.message == tsconfig.errors.GET_PROJECT_JSON_PARSE_FAILED) { - let details: tsconfig.GET_PROJECT_JSON_PARSE_FAILED_Details = query.error.details; - errors = [ - { - filePath: details.projectFilePath, - startPos: { line: 0, col: 0 }, - endPos: { line: 0, col: 0 }, - message: "The project file contains invalid JSON", - preview: details.projectFilePath, - } - ] - } - if (query.error.message == tsconfig.errors.GET_PROJECT_PROJECT_FILE_INVALID_OPTIONS) { - let details: tsconfig.GET_PROJECT_PROJECT_FILE_INVALID_OPTIONS_Details = query.error.details; - errors = [ - { - filePath: details.projectFilePath, - startPos: { line: 0, col: 0 }, - endPos: { line: 0, col: 0 }, - message: "The project file contains invalid options", - preview: details.errorMessage, - } - ] - } - if (query.error.message == tsconfig.errors.GET_PROJECT_GLOB_EXPAND_FAILED) { - let details: tsconfig.GET_PROJECT_GLOB_EXPAND_FAILED_Details = query.error.details; - errors = [ - { - filePath: details.projectFilePath, - startPos: { line: 0, col: 0 }, - endPos: { line: 0, col: 0 }, - message: "Failed to expand the glob for the project file", - preview: details.errorMessage, - } - ] - } - if (query.error.message === tsconfig.errors.GET_PROJECT_NO_PROJECT_FOUND) { - let details: tsconfig.GET_PROJECT_NO_PROJECT_FOUND_Details = query.error.details; - errors = [ - { - filePath: details.projectFilePath, - startPos: { line: 0, col: 0 }, - endPos: { line: 0, col: 0 }, - message: "No project file found. Please use the 'Create tsconfig.json project file' command", - preview: '', - } - ] - } - } - mainPanelView.errorView.setErrors(query.projectFilePath, errors); - return resolve({}); -} - -export function notifySuccess(query: { message: string }): Promise<{}> { - atom.notifications.addSuccess(query.message); - return resolve({}); -} - -export function buildUpdate(query: BuildUpdate): Promise<{}> { - mainPanelView.panelView.setBuildProgress(query); - return resolve({}); -} - -export interface Test { } diff --git a/menus/atomts-menus.cson b/menus/atomts-menus.cson index 1149331d2..efda39830 100644 --- a/menus/atomts-menus.cson +++ b/menus/atomts-menus.cson @@ -7,6 +7,7 @@ 'submenu': [ { 'label': 'Build', 'command': 'typescript:build' } { 'label': 'Go To Declaration', 'command': 'typescript:go-to-declaration' } + { 'label': 'Return From Declaration', 'command': 'typescript:return-from-declaration' } ] ] } diff --git a/package.json b/package.json index 11a0a30bd..64728a834 100644 --- a/package.json +++ b/package.json @@ -1,46 +1,41 @@ { "name": "atom-typescript", - "version": "10.1.14", + "version": "11.0.3", "main": "./dist/main/atomts", - "bin": { - "atbuild": "./dist/main/bin/atbuild" - }, - "preferGlobal": "true", + "preferGlobal": true, "description": "The only TypeScript plugin you will ever need.", + "activationHooks": [ + "atom-typescript:grammar-used" + ], "scripts": { - "build": "ts-node scripts/grammar.ts", - "test": "tsc -p ./lib && tsc --noEmit -p ./scripts", - "prepublish": "typings install" + "build": "tsc -p ./lib", + "grammar": "ts-node scripts/grammar.ts", + "test": "tsc --noEmit -p ./lib && tsc --noEmit -p ./scripts" }, "engines": { "atom": ">=0.199.0 <2.0.0", "node": "*" }, - "providedServices": { - "autocomplete.provider": { - "versions": { - "2.0.0": "provide" - } - }, - "linter": { + "consumedServices": { + "linter-indie": { "versions": { - "1.0.0": "provideLinter" + "^1.0.0": "consumeLinter" } }, - "hyperclick.provider": { + "status-bar": { "versions": { - "0.0.0": "getHyperclickProvider" + "^1.0.0": "consumeStatusBar" } } }, - "consumedServices": { - "snippets": { + "providedServices": { + "autocomplete.provider": { "versions": { - "0.1.0": "consumeSnippets" + "2.0.0": "provide" } } }, - "homepage": "http://atom.io/packages/atom-typescript", + "homepage": "https://github.com/TypeStrong/atom-typescript", "repository": { "type": "git", "url": "https://github.com/TypeStrong/atom-typescript.git" @@ -50,36 +45,32 @@ "url": "https://github.com/TypeStrong/atom-typescript/issues" }, "dependencies": { - "atom-package-deps": "^2.0.3", + "atom-package-deps": "4.4.1", "atom-space-pen-views": "^2.0.4", - "babel": "^5.6.23", - "basarat-text-buffer": "6.0.0", - "byots": "2.1.0-dev.20161029.21.55", - "d3": "^3.5.5", - "detect-indent": "^4.0.0", - "detect-newline": "^2.1.0", + "byline": "^5.0.0", "emissary": "^1.3.3", "escape-html": "^1.0.1", - "findup": "^0.1.5", "fuzzaldrin": "^2.1.0", - "glob": "^5.0.15", - "htmltojsx": "0.2.4", - "immutable": "^3.7.3", - "json2dts": "0.0.1", - "mkdirp": "^0.5.0", - "react": "^0.13.3", - "season": "^5.1.4", + "jsx-render-dom": "0.1.2", + "lodash": "^4.17.2", + "resolve": "1.1.7", "tsconfig": "^2.2.0", - "typescript": "^2.1.4", + "tslib": "1.2.0", + "typescript": "2.3.0-dev.20170319", "xtend": "^4.0.0" }, "devDependencies": { + "@types/atom": "0.0.35", + "@types/byline": "^4.2.31", "@types/cson": "0.0.30", + "@types/fuzzaldrin": "^2.1.0", + "@types/lodash": "^4.14.51", + "@types/resolve": "0.0.4", "cson": "^3.0.2", "mz": "^2.1.0", "plist": "2.0.1", "popsicle": "8.2.0", - "typings": "0.7.9" + "ts-node": "1.7.0" }, "package-deps": [ "linter" diff --git a/pull_request_template.md b/pull_request_template.md index 52a807bab..c2d31550e 100644 --- a/pull_request_template.md +++ b/pull_request_template.md @@ -1,2 +1,2 @@ -[ ] All compiled assets are included (atom packages are git tags and hence the built files need to be a part of the source control) +- [ ] All compiled assets are included (atom packages are git tags and hence the built files need to be a part of the source control) diff --git a/scripts/grammar.ts b/scripts/grammar.ts index 4830b6df1..50c5e9a87 100644 --- a/scripts/grammar.ts +++ b/scripts/grammar.ts @@ -1,5 +1,3 @@ -/// - import * as cson from "cson" import * as fs from "fs" import * as path from "path" diff --git a/scripts/tsconfig.json b/scripts/tsconfig.json index 0a5f24a9d..375f3e954 100644 --- a/scripts/tsconfig.json +++ b/scripts/tsconfig.json @@ -1,7 +1,8 @@ { "compilerOptions": { "module": "commonjs", - "moduleResolution": "node" + "moduleResolution": "node", + "types": ["node"] }, "compileOnSave": false } diff --git a/snippets/typescript-snippets.cson b/snippets/typescript-snippets.cson index 636ab8ff2..9d0fa617f 100644 --- a/snippets/typescript-snippets.cson +++ b/snippets/typescript-snippets.cson @@ -143,3 +143,6 @@ 'body': """ #!/usr/bin/env node """ + 'console.log': + 'prefix': 'log' + 'body': 'console.log(${1})' diff --git a/styles/ast-view.less b/styles/ast-view.less deleted file mode 100644 index 025d3baa0..000000000 --- a/styles/ast-view.less +++ /dev/null @@ -1,25 +0,0 @@ -.ast-view{ - overflow-y: auto; - - // Style the svg - .node rect { - cursor: pointer; - fill: #fff; - fill-opacity: .9; - stroke: black; - stroke-width: 1.5px; - } - - .node text { - font: 11px sans-serif; - font-weight: bold; - pointer-events: none; - fill: white; - } - - path.link { - fill: none; - stroke: #9ecae1; - stroke-width: 1.5px; - } -} diff --git a/styles/atomts-file-semantic-view.less b/styles/atomts-file-semantic-view.less deleted file mode 100644 index 2ea50d2d9..000000000 --- a/styles/atomts-file-semantic-view.less +++ /dev/null @@ -1,115 +0,0 @@ -// The ui-variables file is provided by base themes provided by Atom. -// -// See https://github.com/atom/atom-dark-ui/blob/master/stylesheets/ui-variables.less -// for a full listing of what's available. -@import "ui-variables"; - -@font-face { - font-family: 'symbol-icons'; - src: url('atom://symbols-tree-view/icons/symbol-icons.woff') format('woff'); - font-weight: normal; - font-style: normal; -} - -.symbols-tree-view { - width: 200px; - height: 100%; - padding: 4px; - position: relative; - overflow-y: auto; - overflow-x: hidden; -} - -.symbols-context-menu { - position: absolute; - z-index: 1; - width: 120px; - .hidden-input { - position: absolute; - width: 0; - height: 0; - border: none; - } - .select-list.popover-list { - width: 100%; - min-width: 100%; - ol { - margin-top: 0; - .separator { - background: @background-color-highlight; - height: 1px; - } - li:hover { - background: @background-color-highlight; - } - } - } -} - -@symbol-class: '\e600'; -@symbol-struct: '\e601'; -@symbol-macro: '\e602'; -@symbol-typedef: '\e603'; -@symbol-union: '\e604'; -@symbol-interface:'\e605'; -@symbol-enum: '\e606'; -@symbol-variable: '\e607'; -@symbol-function: '\e608'; -@symbol-namespace:'\e609'; - -.symbol-icon(@name) { - font-family: 'symbol-icons'; - content: @@name; -} - -.symbols-tree-view .icon-function::before { - .symbol-icon(symbol-function); -} - -.symbols-tree-view .icon-class::before { - .symbol-icon(symbol-class); -} - -.symbols-tree-view .icon-namespace::before { - .symbol-icon(symbol-namespace); -} - -.symbols-tree-view .icon-struct::before { - .symbol-icon(symbol-struct); -} - -.symbols-tree-view .icon-variable::before { - .symbol-icon(symbol-variable); -} - -.symbols-tree-view .icon-method::before { - .symbol-icon(symbol-function); -} - -.symbols-tree-view .icon-field::before { - .symbol-icon(symbol-variable); -} - -.symbols-tree-view .icon-member::before { - .symbol-icon(symbol-variable); -} - -.symbols-tree-view .icon-interface::before { - .symbol-icon(symbol-interface); -} - -.symbols-tree-view .icon-enum::before { - .symbol-icon(symbol-enum); -} - -.symbols-tree-view .icon-typedef::before { - .symbol-icon(symbol-typedef); -} - -.symbols-tree-view .icon-macro::before { - .symbol-icon(symbol-macro); -} - -.symbols-tree-view .icon-union::before { - .symbol-icon(symbol-union); -} \ No newline at end of file diff --git a/styles/atomts-grammar-syntax.less b/styles/atomts-grammar-syntax.less index 0c77710b0..9de621488 100644 --- a/styles/atomts-grammar-syntax.less +++ b/styles/atomts-grammar-syntax.less @@ -10,7 +10,7 @@ atom-text-editor.editor { } .syntax--keyword.syntax--debugger { - background-color: lime; + background-color: lime; } } } diff --git a/styles/atomts-r-view.less b/styles/atomts-r-view.less deleted file mode 100644 index ecf420324..000000000 --- a/styles/atomts-r-view.less +++ /dev/null @@ -1,3 +0,0 @@ -.atomts-r-view{ - background: white; -} diff --git a/styles/dependency-view.less b/styles/dependency-view.less deleted file mode 100644 index 93014b5ce..000000000 --- a/styles/dependency-view.less +++ /dev/null @@ -1,136 +0,0 @@ -.dependency-view { - overflow-y: auto; - background-color: white; - .link { - fill: none; - stroke: #666; - stroke-width: 1.5px; - opacity: 0.5; - transition-property: opacity; - transition-duration: .2s; - &.incomming { - stroke: green; - opacity: 0.9; - } - &.outgoing { - stroke: red; - opacity: 0.9; - } - &.dimmed{ - opacity: 0.05; - } - &.filtered-out{ - opacity: 0; - } - } - #licensing { - fill: green; - } - circle { - fill: #ccc; - stroke: #333; - stroke-width: 1.5px; - transition-property: opacity,fill; - transition-duration: .2s; - opacity: 1; - &.inonly { - fill: green; - } - &.outonly { - fill: blue; - } - &.circular { - fill: red; - } - &.fixed { - // Some other day: fill: yellow; - } - &.hovering { - opacity: 1; - fill: #b94431; - } - &.not-hovering { - opacity: 0.05; - } - &.filtered-out { - opacity: 0; - } - } - text { - font: 10px sans-serif; - pointer-events: none; - text-shadow: 0 1px 0 #fff, 1px 0 0 #fff, 0 -1px 0 #fff, -1px 0 0 #fff; - &.dimmed { - opacity: 0.05; - } - &.filtered-out { - opacity: 0; - } - } - g.dimmed { - stroke-opacity: 0.05; - } - .graph { - .filter-section { - position: absolute; - top: 10px; - right: 10px; - width: 200px; - } - .copy-message { - position: absolute; - top: 60px; - right: 10px; - width: 200px; - } - .general-messages { - h3 { - margin-top: 10px; - margin-bottom: 5px; - } - position: absolute; - top: 90px; - right: 10px; - width: 200px; - bottom: 10px; - padding: 5px; - overflow: auto; - background: rgba(200,200,200,.15); - } - } - .control-zoom { - position: absolute; - top: 10px; - left: 10px; - background: rgba(0, 0, 0, 0.25); - padding: 5px; - border-radius: 7px; - z-index: 100; - display: inline-block; - // Because I don't have time to enable this right now - display: none; - } - .control-zoom a { - background: rgba(255, 255, 255, 0.75); - background-position: 50% 50%; - background-repeat: no-repeat; - display: block; - width: 19px; - height: 19px; - border-radius: 4px; - } - .control-zoom a:last-child { - margin: 0; - } - .control-zoom a:hover { - background-color: white; - } - .control-zoom > .control-zoom-in { - background-image: url(data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAkAAAAJAQMAAADaX5RTAAAAGXRFWHRTb2Z0d2FyZQBBZG9iZSBJbWFnZVJlYWR5ccllPAAAAyBpVFh0WE1MOmNvbS5hZG9iZS54bXAAAAAAADw/eHBhY2tldCBiZWdpbj0i77u/IiBpZD0iVzVNME1wQ2VoaUh6cmVTek5UY3prYzlkIj8+IDx4OnhtcG1ldGEgeG1sbnM6eD0iYWRvYmU6bnM6bWV0YS8iIHg6eG1wdGs9IkFkb2JlIFhNUCBDb3JlIDUuMC1jMDYwIDYxLjEzNDc3NywgMjAxMC8wMi8xMi0xNzozMjowMCAgICAgICAgIj4gPHJkZjpSREYgeG1sbnM6cmRmPSJodHRwOi8vd3d3LnczLm9yZy8xOTk5LzAyLzIyLXJkZi1zeW50YXgtbnMjIj4gPHJkZjpEZXNjcmlwdGlvbiByZGY6YWJvdXQ9IiIgeG1sbnM6eG1wPSJodHRwOi8vbnMuYWRvYmUuY29tL3hhcC8xLjAvIiB4bWxuczp4bXBNTT0iaHR0cDovL25zLmFkb2JlLmNvbS94YXAvMS4wL21tLyIgeG1sbnM6c3RSZWY9Imh0dHA6Ly9ucy5hZG9iZS5jb20veGFwLzEuMC9zVHlwZS9SZXNvdXJjZVJlZiMiIHhtcDpDcmVhdG9yVG9vbD0iQWRvYmUgUGhvdG9zaG9wIENTNSBXaW5kb3dzIiB4bXBNTTpJbnN0YW5jZUlEPSJ4bXAuaWlkOkUwRTZCRkI3NjQzNzExRTBBQUI3RTAwMUU2MTZDRkQ5IiB4bXBNTTpEb2N1bWVudElEPSJ4bXAuZGlkOkUwRTZCRkI4NjQzNzExRTBBQUI3RTAwMUU2MTZDRkQ5Ij4gPHhtcE1NOkRlcml2ZWRGcm9tIHN0UmVmOmluc3RhbmNlSUQ9InhtcC5paWQ6RTBFNkJGQjU2NDM3MTFFMEFBQjdFMDAxRTYxNkNGRDkiIHN0UmVmOmRvY3VtZW50SUQ9InhtcC5kaWQ6RTBFNkJGQjY2NDM3MTFFMEFBQjdFMDAxRTYxNkNGRDkiLz4gPC9yZGY6RGVzY3JpcHRpb24+IDwvcmRmOlJERj4gPC94OnhtcG1ldGE+IDw/eHBhY2tldCBlbmQ9InIiPz7cwPMXAAAABlBMVEUAAAD///+l2Z/dAAAAAnRSTlP/AOW3MEoAAAARSURBVAhbY3jcwABBcAATAQBxlwhT4XiahwAAAABJRU5ErkJggg==); - margin-bottom: 5px; - } - .control-zoom > .control-zoom-out { - background-image: url(data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAkAAAAJAQMAAADaX5RTAAAAGXRFWHRTb2Z0d2FyZQBBZG9iZSBJbWFnZVJlYWR5ccllPAAAAyBpVFh0WE1MOmNvbS5hZG9iZS54bXAAAAAAADw/eHBhY2tldCBiZWdpbj0i77u/IiBpZD0iVzVNME1wQ2VoaUh6cmVTek5UY3prYzlkIj8+IDx4OnhtcG1ldGEgeG1sbnM6eD0iYWRvYmU6bnM6bWV0YS8iIHg6eG1wdGs9IkFkb2JlIFhNUCBDb3JlIDUuMC1jMDYwIDYxLjEzNDc3NywgMjAxMC8wMi8xMi0xNzozMjowMCAgICAgICAgIj4gPHJkZjpSREYgeG1sbnM6cmRmPSJodHRwOi8vd3d3LnczLm9yZy8xOTk5LzAyLzIyLXJkZi1zeW50YXgtbnMjIj4gPHJkZjpEZXNjcmlwdGlvbiByZGY6YWJvdXQ9IiIgeG1sbnM6eG1wPSJodHRwOi8vbnMuYWRvYmUuY29tL3hhcC8xLjAvIiB4bWxuczp4bXBNTT0iaHR0cDovL25zLmFkb2JlLmNvbS94YXAvMS4wL21tLyIgeG1sbnM6c3RSZWY9Imh0dHA6Ly9ucy5hZG9iZS5jb20veGFwLzEuMC9zVHlwZS9SZXNvdXJjZVJlZiMiIHhtcDpDcmVhdG9yVG9vbD0iQWRvYmUgUGhvdG9zaG9wIENTNSBXaW5kb3dzIiB4bXBNTTpJbnN0YW5jZUlEPSJ4bXAuaWlkOkU5MjRDMEQ5NjQzNzExRTBCM0JDQkU2MzVGQTBCNjRDIiB4bXBNTTpEb2N1bWVudElEPSJ4bXAuZGlkOkU5MjRDMERBNjQzNzExRTBCM0JDQkU2MzVGQTBCNjRDIj4gPHhtcE1NOkRlcml2ZWRGcm9tIHN0UmVmOmluc3RhbmNlSUQ9InhtcC5paWQ6RTkyNEMwRDc2NDM3MTFFMEIzQkNCRTYzNUZBMEI2NEMiIHN0UmVmOmRvY3VtZW50SUQ9InhtcC5kaWQ6RTkyNEMwRDg2NDM3MTFFMEIzQkNCRTYzNUZBMEI2NEMiLz4gPC9yZGY6RGVzY3JpcHRpb24+IDwvcmRmOlJERj4gPC94OnhtcG1ldGE+IDw/eHBhY2tldCBlbmQ9InIiPz7uh53jAAAABlBMVEUAAAD///+l2Z/dAAAAAnRSTlP/AOW3MEoAAAARSURBVAhbY/jfwABBcAATAQB6xwj7vHGbwAAAAABJRU5ErkJggg==); - margin-bottom: 5px; - } -} diff --git a/styles/documentationview.less b/styles/documentationview.less deleted file mode 100644 index c9296b0a6..000000000 --- a/styles/documentationview.less +++ /dev/null @@ -1,78 +0,0 @@ -// Ref https://github.com/tststs/atom-ternjs/blob/4616908855ac2efd1e2f3a1129a4eb4e47b78b52/stylesheets/atom-ternjs.less -@import "ui-variables"; -@atom-ts-height: 180px; - -.atom-ts-documentation > div, atom-ts-reference > div > div { - max-height: @atom-ts-height; - overflow-y: auto; -} - -.atom-ts-documentation { - position: absolute; - right: calc(@component-padding + 10); - background: fade(@overlay-background-color, 90%); - border: 1px solid fade(@base-border-color, 20%); - color: @text-color; - border-radius: @component-border-radius; - width: 40%; - min-height: @atom-ts-height; - max-width: 640px; - opacity: 0; - pointer-events: none; - transition: opacity .2s ease; - - // I shouldn't need to do this. Check why we have to do this - // also should use @scrollbar-background-color; at some point : https://github.com/TypeStrong/atom-typescript/issues/120 - ::-webkit-scrollbar { - width: 8px; - height: 8px; - } - ::-webkit-scrollbar-track, - ::-webkit-scrollbar-corner { - background: @pane-item-background-color; - } - ::-webkit-scrollbar-thumb { - background: @base-border-color; - border-radius: 5px; - box-shadow: 0 0 1px black inset; - } - - &.active { - opacity: 1; - pointer-events: auto; - } - - &.top { - top: calc(@component-padding + 36); - } - - &.middle { - top: calc(~'50% - '(@atom-ts-height / 2)); - } - - &.bottom { - bottom: calc(@component-padding + 26); - } - - h2 { - margin: 0; - line-height: 1.4em; - margin-top: -0.2em; - } - - p { - margin-top: 10px; - > span { - display: block; - padding-top: 4px; - } - } - - .link { - cursor: pointer; - color: @text-color-highlight; - &:hover { - text-decoration: underline; - } - } -} diff --git a/styles/gutter.atom-text-editor.less b/styles/gutter.less similarity index 100% rename from styles/gutter.atom-text-editor.less rename to styles/gutter.less diff --git a/styles/highlights.less b/styles/highlights.less new file mode 100644 index 000000000..29df648b6 --- /dev/null +++ b/styles/highlights.less @@ -0,0 +1,11 @@ +@import "ui-variables"; + +atom-text-editor.editor { + .highlights { + .atom-typescript-occurrence { + .region { + border-bottom: 1px solid @text-color; + } + } + } +} diff --git a/styles/semantic-view.less b/styles/semantic-view.less deleted file mode 100644 index 2bf226c62..000000000 --- a/styles/semantic-view.less +++ /dev/null @@ -1,109 +0,0 @@ -// From https://github.com/xndcn/symbols-tree-view -@import "ui-variables"; -@font-face { - font-family: 'symbol-icons'; - src: url('atom://atom-typescript/images/symbol-icons.woff') format('woff'); - font-weight: normal; - font-style: normal; -} - -@symbol-class: '\e600'; -@symbol-struct: '\e601'; -@symbol-macro: '\e602'; -@symbol-typedef: '\e603'; -@symbol-union: '\e604'; -@symbol-interface: '\e605'; -@symbol-enum: '\e606'; -@symbol-variable: '\e607'; -@symbol-function: '\e608'; -@symbol-namespace: '\e609'; -.symbol-icon(@name) { - font-family: 'symbol-icons'; - content: @@name; -} -.atomts-semantic-view { - max-width: 250px; - // needed otherwise the panel takes up all the space and doesn't scroll - max-height: 100%; - overflow-y: auto; - padding: 10px; - .selected { - background: @background-color-highlight; - } - - .node{ - cursor: pointer; - } - - .icon-class::before { - .symbol-icon(symbol-class); - } - .icon-struct::before { - .symbol-icon(symbol-struct); - } - .icon-variable::before { - .symbol-icon(symbol-variable); - } - - .icon-field::before { - .symbol-icon(symbol-variable); - } - .icon-member::before { - .symbol-icon(symbol-variable); - } - .icon-interface::before { - .symbol-icon(symbol-interface); - } - .icon-enum::before { - .symbol-icon(symbol-enum); - } - .icon-typedef::before { - .symbol-icon(symbol-typedef); - } - .icon-macro::before { - .symbol-icon(symbol-macro); - } - .icon-union::before { - .symbol-icon(symbol-union); - } - - - - .icon-module::before { - .symbol-icon(symbol-macro); - } - - // variable like - .icon-var::before { - .symbol-icon(symbol-variable); - } - .icon-property::before { - .symbol-icon(symbol-variable); - } - .icon-alias::before { - .symbol-icon(symbol-variable); - } - - // function like - .icon-function::before { - .symbol-icon(symbol-function); - } - .icon-constructor::before { - .symbol-icon(symbol-function); - } - .icon-method::before { - .symbol-icon(symbol-function); - } - .icon-setter::before { - .symbol-icon(symbol-function); - } - .icon-getter::before { - .symbol-icon(symbol-function); - } - - // module like - .icon-namespace::before { - .symbol-icon(symbol-namespace); - } - -} diff --git a/tslint.json b/tslint.json new file mode 100644 index 000000000..0967ef424 --- /dev/null +++ b/tslint.json @@ -0,0 +1 @@ +{} diff --git a/typings.json b/typings.json deleted file mode 100644 index a1ded82c5..000000000 --- a/typings.json +++ /dev/null @@ -1,11 +0,0 @@ -{ - "dependencies": { - "source-map": "github:typings/typed-source-map#86c25e7a550d5af7a63d979625602c17cce157f6", - "tsconfig": "npm:tsconfig" - }, - "ambientDependencies": { - "glob": "github:DefinitelyTyped/DefinitelyTyped/glob/glob.d.ts#a61804f9d999ade20b29687a9eed458d7d845b0e", - "node": "github:DefinitelyTyped/DefinitelyTyped/node/node.d.ts#fd8deba9647874c303e50dc1d96be1ff0b4e9b85", - "pathwatcher": "github:DefinitelyTyped/DefinitelyTyped/pathwatcher/pathwatcher.d.ts#aee42d3e873a332bda7ff2a77d0c5973a11cd2d3" - } -} diff --git a/views/renameView.html.coffee b/views/renameView.html.coffee index d01125819..0833d7403 100644 --- a/views/renameView.html.coffee +++ b/views/renameView.html.coffee @@ -17,6 +17,4 @@ module.exports = @div class: 'editor-container', => @subview 'newNameEditor', new TextEditorView(mini: true, placeholderText: 'new name') - @div {outlet:'fileCount'}, => return - @br {} @div {class: 'highlight-error', style:'display:none', outlet:'validationMessage'}, diff --git a/views/views.d.ts b/views/views.d.ts deleted file mode 100644 index c9d69f1f2..000000000 --- a/views/views.d.ts +++ /dev/null @@ -1,10 +0,0 @@ - -// I find it easiest to create Views in CoffeeScript -// This is because of the way that Atom works -// This means that views a losely coupled with the API which we declare here -// But atleaset the views are readable - -declare class AtomView { - // Methods from base View - remove(); -}