From 67c15e3aecec4c1a6be5b32615aa981ae91ba279 Mon Sep 17 00:00:00 2001 From: Guntars Asmanis-Graham Date: Fri, 18 Nov 2016 14:07:08 -0500 Subject: [PATCH 01/70] Update Typescript --- dist/main/atom/views/rView.js | 2 +- dist/main/atom/views/renameView.js | 2 +- dist/main/utils/fsUtil.js | 2 +- grammars/ts.cson | 330 ++++++++++++++++++-------- grammars/tsx.cson | 363 +++++++++++++++++++---------- package.json | 5 +- 6 files changed, 484 insertions(+), 220 deletions(-) diff --git a/dist/main/atom/views/rView.js b/dist/main/atom/views/rView.js index 05d00742e..b1b34d01f 100644 --- a/dist/main/atom/views/rView.js +++ b/dist/main/atom/views/rView.js @@ -62,5 +62,5 @@ var RView = (function (_super) { }); return RView; }(sp.ScrollView)); -exports.RView = RView; RView.protocol = 'atomtsview:'; +exports.RView = RView; diff --git a/dist/main/atom/views/renameView.js b/dist/main/atom/views/renameView.js index 7a52926be..9c3bc3bd0 100644 --- a/dist/main/atom/views/renameView.js +++ b/dist/main/atom/views/renameView.js @@ -74,8 +74,8 @@ var RenameView = (function (_super) { }; return RenameView; }(view.View)); -exports.RenameView = RenameView; RenameView.content = html; +exports.RenameView = RenameView; var panel; function attach() { exports.panelView = new RenameView({}); diff --git a/dist/main/utils/fsUtil.js b/dist/main/utils/fsUtil.js index 1cde4272c..69cfb6d28 100644 --- a/dist/main/utils/fsUtil.js +++ b/dist/main/utils/fsUtil.js @@ -7,7 +7,7 @@ var path = require("path"); function resolve() { var args = []; for (var _i = 0; _i < arguments.length; _i++) { - args[_i - 0] = arguments[_i]; + args[_i] = arguments[_i]; } return consistentPath(path.resolve.apply(path, args)); } diff --git a/grammars/ts.cson b/grammars/ts.cson index 140eb15ed..1126d540e 100644 --- a/grammars/ts.cson +++ b/grammars/ts.cson @@ -1,6 +1,6 @@ -# This file is generated by "scripts/grammar.js" -# Last generated: Wed, 26 Oct 2016 21:17:08 GMT +# This file is generated by "scripts/grammar.ts" +# Last generated: Fri, 18 Nov 2016 19:03:32 GMT name: "TypeScript" scopeName: "source.ts" @@ -9,9 +9,19 @@ fileTypes: [ ] uuid: "ef98eb90-bf9b-11e4-bb52-0800200c9a66" patterns: [ + { + include: "#directives" + } { include: "#statements" } + { + name: "comment.line.shebang.ts" + match: "\\A(#!).*(?=$)" + captures: + "1": + name: "punctuation.definition.comment.ts" + } ] repository: statements: @@ -52,9 +62,6 @@ repository: { include: "#string" } - { - include: "#regex" - } { include: "#template" } @@ -116,21 +123,44 @@ repository: } ] "var-single-variable": - name: "meta.var-single-variable.expr.ts" - begin: "([_$[:alpha:]][_$[:alnum:]]*)" - beginCaptures: - "1": - name: "meta.definition.variable.ts variable.other.readwrite.ts" - end: "(?=$|[;,=}]|(\\s+(of|in)\\s+))" patterns: [ { - include: "#type-annotation" - } - { - include: "#string" + name: "meta.var-single-variable.expr.ts" + begin: "(?x)([_$[:alpha:]][_$[:alnum:]]*)(?=\\s* (=\\s*( (async\\s+) | (function\\s*[(<]) | (function\\s+) | ([_$[:alpha:]][_$[:alnum:]]*\\s*=>) | ((<([^<>]|\\<[^<>]+\\>)+>\\s*)?\\(([^()]|\\([^()]*\\))*\\)(\\s*:\\s*(.)*)?\\s*=>)) ) | (:\\s*( (<) | ([(]\\s*( ([)]) | (\\.\\.\\.) | ([_$[:alnum:]]+\\s*( ([:,?=])| ([)]\\s*=>) )) ))) ))" + beginCaptures: + "1": + name: "meta.definition.variable.ts entity.name.function.ts" + end: "(?=$|[;,=}]|(\\s+(of|in)\\s+))" + patterns: [ + { + include: "#type-annotation" + } + { + include: "#string" + } + { + include: "#comment" + } + ] } { - include: "#comment" + name: "meta.var-single-variable.expr.ts" + begin: "([_$[:alpha:]][_$[:alnum:]]*)" + beginCaptures: + "1": + name: "meta.definition.variable.ts variable.other.readwrite.ts" + end: "(?=$|[;,=}]|(\\s+(of|in)\\s+))" + patterns: [ + { + include: "#type-annotation" + } + { + include: "#string" + } + { + include: "#comment" + } + ] } ] "destructuring-variable": @@ -174,26 +204,14 @@ repository: include: "#comment" } { - begin: "([_$[:alpha:]][_$[:alnum:]]*)\\s*(:)" - beginCaptures: - "1": - name: "variable.object.property.ts" - "2": - name: "punctuation.destructuring.ts" + begin: "(?=(([_$[:alpha:]][_$[:alnum:]]*)|(\\'[^']*\\')|(\\\"[^\"]*\\\")|(\\[([^\\[\\]]|\\[[^\\[\\]]+\\])+\\]))\\s*(:))" end: "(?=,|\\})" patterns: [ { - include: "#object-binding-pattern" + include: "#object-binding-element-propertyName" } { - include: "#array-binding-pattern" - } - { - name: "meta.definition.variable.ts variable.other.readwrite.ts" - match: "([_$[:alpha:]][_$[:alnum:]]*)" - } - { - include: "#variable-initializer" + include: "#binding-element" } ] } @@ -210,7 +228,25 @@ repository: include: "#punctuation-comma" } ] - "array-binding-element": + "object-binding-element-propertyName": + begin: "(?=(([_$[:alpha:]][_$[:alnum:]]*)|(\\'[^']*\\')|(\\\"[^\"]*\\\")|(\\[([^\\[\\]]|\\[[^\\[\\]]+\\])+\\]))\\s*(:))" + end: "(:)" + endCaptures: + "0": + name: "punctuation.destructuring.ts" + patterns: [ + { + include: "#string" + } + { + include: "#array-literal" + } + { + name: "variable.object.property.ts" + match: "([_$[:alpha:]][_$[:alnum:]]*)" + } + ] + "binding-element": patterns: [ { include: "#comment" @@ -227,9 +263,6 @@ repository: { include: "#variable-initializer" } - { - include: "#punctuation-comma" - } ] "destructuring-variable-rest": match: "(?:(\\.\\.\\.)\\s*)?([_$[:alpha:]][_$[:alnum:]]*)" @@ -267,7 +300,10 @@ repository: name: "punctuation.definition.binding-pattern.array.ts" patterns: [ { - include: "#array-binding-element" + include: "#binding-element" + } + { + include: "#punctuation-comma" } ] "ternary-expression": @@ -354,10 +390,10 @@ repository: include: "#expression-operators" } { - include: "#support-objects" + include: "#function-call" } { - include: "#function-call" + include: "#support-objects" } { include: "#identifiers" @@ -535,12 +571,15 @@ repository: ] } { - begin: "(?=(?:(?:\\'[^']*\\')|(?:\\\"[^\"]*\\\")))" + begin: "(?=((\\'[^']*\\')|(\\\"[^\"]*\\\")|(\\[([^\\[\\]]|\\[[^\\[\\]]+\\])+\\])))" end: "(?=,|\\}|$)" patterns: [ { include: "#string" } + { + include: "#array-literal" + } { include: "#comment" } @@ -830,7 +869,7 @@ repository: include: "#type-parameters" } { - match: "([_$[:alpha:]][_$[:alnum:]]*)\\s*(\\.)" + match: "([_$[:alpha:]][_$[:alnum:]]*)\\s*(\\.)(?=\\s*[_$[:alpha:]][_$[:alnum:]]*(\\s*\\.\\s*[_$[:alpha:]][_$[:alnum:]]*)*\\s*([,<{]|extends|implements|//|/\\*))" captures: "1": name: "entity.name.type.module.ts" @@ -838,11 +877,14 @@ repository: name: "punctuation.accessor.ts" } { - match: "([_$[:alpha:]][_$[:alnum:]]*)" + match: "([_$[:alpha:]][_$[:alnum:]]*)(?=\\s*([,<{]|extends|implements|//|/\\*))" captures: "1": name: "entity.other.inherited-class.ts" } + { + include: "#expression" + } ] "class-or-interface-body": begin: "\\{" @@ -920,6 +962,9 @@ repository: { include: "#indexer-declaration" } + { + include: "#indexer-mapped-type-declaration" + } { include: "#field-declaration" } @@ -947,7 +992,7 @@ repository: ] "field-declaration": name: "meta.field.declaration.ts" - begin: "(?) | ((<([^<>]|\\<[^<>]+\\>)+>\\s*)?\\(([^()]|\\([^()]*\\))*\\)(\\s*:\\s*(.)*)?\\s*=>)) ) | (:\\s*( (<) | ([(]\\s*( ([)]) | (\\.\\.\\.) | ([_$[:alnum:]]+\\s*( ([:,?=])| ([)]\\s*=>) )) ))) ))" + } { name: "meta.definition.property.ts variable.object.property.ts" match: "[_$[:alpha:]][_$[:alnum:]]*" @@ -985,7 +1034,7 @@ repository: ] "method-declaration": name: "meta.method.declaration.ts" - begin: "(?) | ((<([^<>]|\\<[^<>]+\\>)+>\\s*)?\\(([^()]|\\([^()]*\\))*\\)(\\s*:\\s*(.)*)?\\s*=>)) ) | (:\\s*( (<) | ([(]\\s*( ([)]) | (\\.\\.\\.) | ([_$[:alnum:]]+\\s*( ([:,?=])| ([)]\\s*=>) )) ))) ))" + captures: + "1": + name: "storage.modifier.ts" + "2": + name: "storage.modifier.ts" + "3": + name: "keyword.operator.rest.ts" + "4": + name: "entity.name.function.ts" + "5": + name: "keyword.operator.optional.ts" + } + { + match: "(?:\\s*\\b(readonly)\\s+)?(?:\\s*\\b(public|private|protected)\\s+)?(\\.\\.\\.)?\\s*(?) )) ) ) )" + begin: "(?x)( (?= [(]\\s*( ([)]) | (\\.\\.\\.) | ([_$[:alnum:]]+\\s*( ([:,?=])| ([)]\\s*=>) )) ) ) )" end: "(?<=\\))" patterns: [ { @@ -1537,6 +1618,10 @@ repository: name: "keyword.operator.type.ts" match: "[&|]" } + { + name: "keyword.operator.expression.keyof.ts" + match: "(?]|\\<[^<>]+\\>)+>\\s*)?\\()" - beginCaptures: - "1": + begin: "(?=(\\.\\s*)?([_$[:alpha:]][_$[:alnum:]]*)\\s*(<([^<>]|\\<[^<>]+\\>)+>\\s*)?\\()" + end: "(?<=\\))(?!(\\.\\s*)?([_$[:alpha:]][_$[:alnum:]]*)\\s*(<([^<>]|\\<[^<>]+\\>)+>\\s*)?\\()" + patterns: [ + { + include: "#support-objects" + } + { name: "punctuation.accessor.ts" - "2": + match: "\\." + } + { name: "entity.name.function.ts" - end: "(?<=\\))" - patterns: [ + match: "([_$[:alpha:]][_$[:alnum:]]*)" + } { include: "#comment" } @@ -2180,6 +2271,9 @@ repository: { include: "#paren-expression" } + { + include: "#class-or-interface-declaration" + } { include: "#type" } @@ -2194,12 +2288,12 @@ repository: } { name: "meta.object.member.ts" - begin: "(?=(?:(?:\\'[^']*\\')|(?:\\\"[^\"]*\\\")|(?:\\[[^\\]]*\\]))\\s*:)" + begin: "(?=(?:(?:\\'[^']*\\')|(?:\\\"[^\"]*\\\")|(?:\\[([^\\[\\]]|\\[[^\\[\\]]+\\])+\\]))\\s*:)" end: "(?=,|\\})" patterns: [ { name: "meta.object-literal.key.ts" - begin: "(?=(?:(?:\\'[^']*\\')|(?:\\\"[^\"]*\\\")|(?:\\[[^\\]]*\\]))\\s*:)" + begin: "(?=(?:(?:\\'[^']*\\')|(?:\\\"[^\"]*\\\")|(?:\\[([^\\[\\]]|\\[[^\\[\\]]+\\])+\\]))\\s*:)" end: ":" endCaptures: "0": @@ -2367,6 +2461,12 @@ repository: name: "keyword.operator.arithmetic.ts" match: "%|\\*|/|-|\\+" } + { + match: "(?<=[_$[:alnum:]])\\s*(/)(?![/*])" + captures: + "1": + name: "keyword.operator.arithmetic.ts" + } ] "typeof-operator": name: "keyword.operator.expression.typeof.ts" @@ -2504,7 +2604,7 @@ repository: patterns: [ { name: "string.regex.ts" - begin: "(?<=[=(:,\\[?+!]|return|case|=>|&&|\\|\\||\\*\\/)\\s*(/)(?![/*+?])(?=.*/)" + begin: "(?<=[=(:,\\[?+!]|return|case|=>|&&|\\|\\||\\*\\/)\\s*(/)(?![/*])(?=(?:[^/\\\\\\[]|\\\\.|\\[([^\\]\\\\]|\\\\.)+\\])+/(?![/*])[gimy]*(?!\\s*[a-zA-Z0-9_$]))" beginCaptures: "1": name: "punctuation.definition.string.begin.ts" @@ -2522,7 +2622,7 @@ repository: } { name: "string.regex.ts" - begin: "/(?![/*])(?=(?:[^/\\\\\\[]|\\\\.|\\[([^\\]\\\\]|\\\\.)+\\])+/(?![/*])[gimy]*(?!\\s*[a-zA-Z0-9_$]))" + begin: "(?\\s*$)" + beginCaptures: + "1": + name: "punctuation.definition.comment.ts" + end: "(?=$)" + patterns: [ + { + name: "meta.tag.ts" + begin: "(<)(reference|amd-dependency|amd-module)" + beginCaptures: + "1": + name: "punctuation.definition.tag.directive.ts" + "2": + name: "entity.name.tag.directive.ts" + end: "/>" + endCaptures: + "0": + name: "punctuation.definition.tag.directive.ts" + patterns: [ + { + name: "entity.other.attribute-name.directive.ts" + match: "path|types|no-default-lib|name" + } + { + name: "keyword.operator.assignment.ts" + match: "=" + } + { + include: "#string" + } + ] + } + ] docblock: patterns: [ { diff --git a/grammars/tsx.cson b/grammars/tsx.cson index bc2267b2c..5872c8624 100644 --- a/grammars/tsx.cson +++ b/grammars/tsx.cson @@ -1,6 +1,6 @@ -# This file is generated by "scripts/grammar.js" -# Last generated: Wed, 26 Oct 2016 21:17:08 GMT +# This file is generated by "scripts/grammar.ts" +# Last generated: Fri, 18 Nov 2016 19:03:32 GMT name: "TypeScriptReact" scopeName: "source.tsx" @@ -9,9 +9,19 @@ fileTypes: [ ] uuid: "805375ec-d614-41f5-8993-5843fe63ea82" patterns: [ + { + include: "#directives" + } { include: "#statements" } + { + name: "comment.line.shebang.ts" + match: "\\A(#!).*(?=$)" + captures: + "1": + name: "punctuation.definition.comment.ts" + } ] repository: statements: @@ -52,9 +62,6 @@ repository: { include: "#string" } - { - include: "#regex" - } { include: "#template" } @@ -116,21 +123,44 @@ repository: } ] "var-single-variable": - name: "meta.var-single-variable.expr.tsx" - begin: "([_$[:alpha:]][_$[:alnum:]]*)" - beginCaptures: - "1": - name: "meta.definition.variable.tsx variable.other.readwrite.tsx" - end: "(?=$|[;,=}]|(\\s+(of|in)\\s+))" patterns: [ { - include: "#type-annotation" - } - { - include: "#string" + name: "meta.var-single-variable.expr.tsx" + begin: "(?x)([_$[:alpha:]][_$[:alnum:]]*)(?=\\s* (=\\s*( (async\\s+) | (function\\s*[(<]) | (function\\s+) | ([_$[:alpha:]][_$[:alnum:]]*\\s*=>) | ((<([^<>]|\\<[^<>]+\\>)+>\\s*)?\\(([^()]|\\([^()]*\\))*\\)(\\s*:\\s*(.)*)?\\s*=>)) ) | (:\\s*( (<) | ([(]\\s*( ([)]) | (\\.\\.\\.) | ([_$[:alnum:]]+\\s*( ([:,?=])| ([)]\\s*=>) )) ))) ))" + beginCaptures: + "1": + name: "meta.definition.variable.tsx entity.name.function.tsx" + end: "(?=$|[;,=}]|(\\s+(of|in)\\s+))" + patterns: [ + { + include: "#type-annotation" + } + { + include: "#string" + } + { + include: "#comment" + } + ] } { - include: "#comment" + name: "meta.var-single-variable.expr.tsx" + begin: "([_$[:alpha:]][_$[:alnum:]]*)" + beginCaptures: + "1": + name: "meta.definition.variable.tsx variable.other.readwrite.tsx" + end: "(?=$|[;,=}]|(\\s+(of|in)\\s+))" + patterns: [ + { + include: "#type-annotation" + } + { + include: "#string" + } + { + include: "#comment" + } + ] } ] "destructuring-variable": @@ -174,26 +204,14 @@ repository: include: "#comment" } { - begin: "([_$[:alpha:]][_$[:alnum:]]*)\\s*(:)" - beginCaptures: - "1": - name: "variable.object.property.tsx" - "2": - name: "punctuation.destructuring.tsx" + begin: "(?=(([_$[:alpha:]][_$[:alnum:]]*)|(\\'[^']*\\')|(\\\"[^\"]*\\\")|(\\[([^\\[\\]]|\\[[^\\[\\]]+\\])+\\]))\\s*(:))" end: "(?=,|\\})" patterns: [ { - include: "#object-binding-pattern" + include: "#object-binding-element-propertyName" } { - include: "#array-binding-pattern" - } - { - name: "meta.definition.variable.tsx variable.other.readwrite.tsx" - match: "([_$[:alpha:]][_$[:alnum:]]*)" - } - { - include: "#variable-initializer" + include: "#binding-element" } ] } @@ -210,7 +228,25 @@ repository: include: "#punctuation-comma" } ] - "array-binding-element": + "object-binding-element-propertyName": + begin: "(?=(([_$[:alpha:]][_$[:alnum:]]*)|(\\'[^']*\\')|(\\\"[^\"]*\\\")|(\\[([^\\[\\]]|\\[[^\\[\\]]+\\])+\\]))\\s*(:))" + end: "(:)" + endCaptures: + "0": + name: "punctuation.destructuring.tsx" + patterns: [ + { + include: "#string" + } + { + include: "#array-literal" + } + { + name: "variable.object.property.tsx" + match: "([_$[:alpha:]][_$[:alnum:]]*)" + } + ] + "binding-element": patterns: [ { include: "#comment" @@ -227,9 +263,6 @@ repository: { include: "#variable-initializer" } - { - include: "#punctuation-comma" - } ] "destructuring-variable-rest": match: "(?:(\\.\\.\\.)\\s*)?([_$[:alpha:]][_$[:alnum:]]*)" @@ -267,7 +300,10 @@ repository: name: "punctuation.definition.binding-pattern.array.tsx" patterns: [ { - include: "#array-binding-element" + include: "#binding-element" + } + { + include: "#punctuation-comma" } ] "ternary-expression": @@ -357,10 +393,10 @@ repository: include: "#expression-operators" } { - include: "#support-objects" + include: "#function-call" } { - include: "#function-call" + include: "#support-objects" } { include: "#identifiers" @@ -538,12 +574,15 @@ repository: ] } { - begin: "(?=(?:(?:\\'[^']*\\')|(?:\\\"[^\"]*\\\")))" + begin: "(?=((\\'[^']*\\')|(\\\"[^\"]*\\\")|(\\[([^\\[\\]]|\\[[^\\[\\]]+\\])+\\])))" end: "(?=,|\\}|$)" patterns: [ { include: "#string" } + { + include: "#array-literal" + } { include: "#comment" } @@ -833,7 +872,7 @@ repository: include: "#type-parameters" } { - match: "([_$[:alpha:]][_$[:alnum:]]*)\\s*(\\.)" + match: "([_$[:alpha:]][_$[:alnum:]]*)\\s*(\\.)(?=\\s*[_$[:alpha:]][_$[:alnum:]]*(\\s*\\.\\s*[_$[:alpha:]][_$[:alnum:]]*)*\\s*([,<{]|extends|implements|//|/\\*))" captures: "1": name: "entity.name.type.module.tsx" @@ -841,11 +880,14 @@ repository: name: "punctuation.accessor.tsx" } { - match: "([_$[:alpha:]][_$[:alnum:]]*)" + match: "([_$[:alpha:]][_$[:alnum:]]*)(?=\\s*([,<{]|extends|implements|//|/\\*))" captures: "1": name: "entity.other.inherited-class.tsx" } + { + include: "#expression" + } ] "class-or-interface-body": begin: "\\{" @@ -923,6 +965,9 @@ repository: { include: "#indexer-declaration" } + { + include: "#indexer-mapped-type-declaration" + } { include: "#field-declaration" } @@ -950,7 +995,7 @@ repository: ] "field-declaration": name: "meta.field.declaration.tsx" - begin: "(?) | ((<([^<>]|\\<[^<>]+\\>)+>\\s*)?\\(([^()]|\\([^()]*\\))*\\)(\\s*:\\s*(.)*)?\\s*=>)) ) | (:\\s*( (<) | ([(]\\s*( ([)]) | (\\.\\.\\.) | ([_$[:alnum:]]+\\s*( ([:,?=])| ([)]\\s*=>) )) ))) ))" + } { name: "meta.definition.property.tsx variable.object.property.tsx" match: "[_$[:alpha:]][_$[:alnum:]]*" @@ -988,7 +1037,7 @@ repository: ] "method-declaration": name: "meta.method.declaration.tsx" - begin: "(?) | ((<([^<>]|\\<[^<>]+\\>)+>\\s*)?\\(([^()]|\\([^()]*\\))*\\)(\\s*:\\s*(.)*)?\\s*=>)) ) | (:\\s*( (<) | ([(]\\s*( ([)]) | (\\.\\.\\.) | ([_$[:alnum:]]+\\s*( ([:,?=])| ([)]\\s*=>) )) ))) ))" + captures: + "1": + name: "storage.modifier.tsx" + "2": + name: "storage.modifier.tsx" + "3": + name: "keyword.operator.rest.tsx" + "4": + name: "entity.name.function.tsx" + "5": + name: "keyword.operator.optional.tsx" + } + { + match: "(?:\\s*\\b(readonly)\\s+)?(?:\\s*\\b(public|private|protected)\\s+)?(\\.\\.\\.)?\\s*(?) )) ) ) )" + begin: "(?x)( (?= [(]\\s*( ([)]) | (\\.\\.\\.) | ([_$[:alnum:]]+\\s*( ([:,?=])| ([)]\\s*=>) )) ) ) )" end: "(?<=\\))" patterns: [ { @@ -1540,6 +1621,10 @@ repository: name: "keyword.operator.type.tsx" match: "[&|]" } + { + name: "keyword.operator.expression.keyof.tsx" + match: "(?]|\\<[^<>]+\\>)+>\\s*)?\\()" - beginCaptures: - "1": + begin: "(?=(\\.\\s*)?([_$[:alpha:]][_$[:alnum:]]*)\\s*(<([^<>]|\\<[^<>]+\\>)+>\\s*)?\\()" + end: "(?<=\\))(?!(\\.\\s*)?([_$[:alpha:]][_$[:alnum:]]*)\\s*(<([^<>]|\\<[^<>]+\\>)+>\\s*)?\\()" + patterns: [ + { + include: "#support-objects" + } + { name: "punctuation.accessor.tsx" - "2": + match: "\\." + } + { name: "entity.name.function.tsx" - end: "(?<=\\))" - patterns: [ + match: "([_$[:alpha:]][_$[:alnum:]]*)" + } { include: "#comment" } @@ -2174,6 +2265,9 @@ repository: { include: "#paren-expression" } + { + include: "#class-or-interface-declaration" + } { include: "#type" } @@ -2188,12 +2282,12 @@ repository: } { name: "meta.object.member.tsx" - begin: "(?=(?:(?:\\'[^']*\\')|(?:\\\"[^\"]*\\\")|(?:\\[[^\\]]*\\]))\\s*:)" + begin: "(?=(?:(?:\\'[^']*\\')|(?:\\\"[^\"]*\\\")|(?:\\[([^\\[\\]]|\\[[^\\[\\]]+\\])+\\]))\\s*:)" end: "(?=,|\\})" patterns: [ { name: "meta.object-literal.key.tsx" - begin: "(?=(?:(?:\\'[^']*\\')|(?:\\\"[^\"]*\\\")|(?:\\[[^\\]]*\\]))\\s*:)" + begin: "(?=(?:(?:\\'[^']*\\')|(?:\\\"[^\"]*\\\")|(?:\\[([^\\[\\]]|\\[[^\\[\\]]+\\])+\\]))\\s*:)" end: ":" endCaptures: "0": @@ -2361,6 +2455,12 @@ repository: name: "keyword.operator.arithmetic.tsx" match: "%|\\*|/|-|\\+" } + { + match: "(?<=[_$[:alnum:]])\\s*(/)(?![/*])" + captures: + "1": + name: "keyword.operator.arithmetic.tsx" + } ] "typeof-operator": name: "keyword.operator.expression.typeof.tsx" @@ -2498,7 +2598,7 @@ repository: patterns: [ { name: "string.regex.tsx" - begin: "(?<=[=(:,\\[?+!]|return|case|=>|&&|\\|\\||\\*\\/)\\s*(/)(?![/*+?])(?=.*/)" + begin: "(?<=[=(:,\\[?+!]|return|case|=>|&&|\\|\\||\\*\\/)\\s*(/)(?![/*])(?=(?:[^/\\\\\\[]|\\\\.|\\[([^\\]\\\\]|\\\\.)+\\])+/(?![/*])[gimy]*(?!\\s*[a-zA-Z0-9_$]))" beginCaptures: "1": name: "punctuation.definition.string.begin.tsx" @@ -2516,7 +2616,7 @@ repository: } { name: "string.regex.tsx" - begin: "/(?![/*])(?=(?:[^/\\\\\\[]|\\\\.|\\[([^\\]\\\\]|\\\\.)+\\])+/(?![/*])[gimy]*(?!\\s*[a-zA-Z0-9_$]))" + begin: "(?\\s*$)" + beginCaptures: + "1": + name: "punctuation.definition.comment.tsx" + end: "(?=$)" + patterns: [ + { + name: "meta.tag.tsx" + begin: "(<)(reference|amd-dependency|amd-module)" + beginCaptures: + "1": + name: "punctuation.definition.tag.directive.tsx" + "2": + name: "entity.name.tag.directive.tsx" + end: "/>" + endCaptures: + "0": + name: "punctuation.definition.tag.directive.tsx" + patterns: [ + { + name: "entity.other.attribute-name.directive.tsx" + match: "path|types|no-default-lib|name" + } + { + name: "keyword.operator.assignment.tsx" + match: "=" + } + { + include: "#string" + } + ] + } + ] docblock: patterns: [ { @@ -3053,7 +3193,6 @@ repository: } ] "jsx-tag-attribute-name": - name: "meta.tag.attribute-name.tsx" match: ''' (?x) \\s* @@ -3067,33 +3206,33 @@ repository: name: "keyword.operator.assignment.tsx" match: "=(?=\\s*(?:'|\"|{|/\\*|//|\\n))" "jsx-string-double-quoted": - name: "string.jsxAttributeValue.quoted.double.tsx" + name: "string.quoted.double.tsx" begin: "\"" end: "\"" beginCaptures: "0": - name: "punctuation.definition.string.jsxAttributeValue.begin.tsx" + name: "punctuation.definition.string.begin.tsx" endCaptures: "0": - name: "punctuation.definition.string.jsxAttributeValue.end.tsx" + name: "punctuation.definition.string.end.tsx" patterns: [ { - include: "#jsx-attributeValue-entities" + include: "#jsx-entities" } ] "jsx-string-single-quoted": - name: "string.jsxAttributeValue.quoted.single.tsx" + name: "string.quoted.single.tsx" begin: "'" end: "'" beginCaptures: "0": - name: "punctuation.definition.string.jsxAttributeValue.begin.tsx" + name: "punctuation.definition.string.begin.tsx" endCaptures: "0": - name: "punctuation.definition.string.jsxAttributeValue.end.tsx" + name: "punctuation.definition.string.end.tsx" patterns: [ { - include: "#jsx-attributeValue-entities" + include: "#jsx-entities" } ] "jsx-entities": @@ -3112,22 +3251,6 @@ repository: match: "&" } ] - "jsx-attributeValue-entities": - patterns: [ - { - name: "constant.character.entity.jsxAttributeValue.tsx" - match: "(&)([a-zA-Z0-9]+|#[0-9]+|#x[0-9a-fA-F]+)(;)" - captures: - "1": - name: "punctuation.definition.entity.jsxAttributeValue.tsx" - "3": - name: "punctuation.definition.entity.jsxAttributeValue.tsx" - } - { - name: "invalid.illegal.bad-ampersand.jsxAttributeValue.tsx" - match: "&" - } - ] "jsx-evaluated-code": name: "meta.embedded.expression.tsx" begin: "{" diff --git a/package.json b/package.json index c16c02412..c8eb4f03d 100644 --- a/package.json +++ b/package.json @@ -54,7 +54,7 @@ "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", + "byots": "2.2.0-dev.20161117.23.11", "d3": "^3.5.5", "detect-indent": "^4.0.0", "detect-newline": "^2.1.0", @@ -70,7 +70,7 @@ "react": "^0.13.3", "season": "^5.1.4", "tsconfig": "^2.2.0", - "typescript": "2.1.0-dev.20161023", + "typescript": "2.2.0-dev.20161118", "xtend": "^4.0.0" }, "devDependencies": { @@ -79,6 +79,7 @@ "mz": "^2.1.0", "plist": "2.0.1", "popsicle": "8.2.0", + "ts-node": "1.7.0", "typings": "0.7.9" }, "package-deps": [ From 7600890e74c30308d4115743c4742afc494ae830 Mon Sep 17 00:00:00 2001 From: Guntars Asmanis-Graham Date: Thu, 24 Nov 2016 23:16:10 -0500 Subject: [PATCH 02/70] Create TypescriptServiceClient --- dist/client/client.js | 119 +++++++++++++++++++++++++++ dist/worker/lib/workerLib.js | 2 +- dist/worker/parent.js | 10 +++ lib/client/client.ts | 153 +++++++++++++++++++++++++++++++++++ lib/tsconfig.json | 1 + lib/worker/lib/workerLib.ts | 2 +- lib/worker/parent.ts | 13 +++ package.json | 4 + scripts/grammar.ts | 2 - scripts/tsconfig.json | 3 +- typings.json | 2 - 11 files changed, 304 insertions(+), 7 deletions(-) create mode 100644 dist/client/client.js create mode 100644 lib/client/client.ts diff --git a/dist/client/client.js b/dist/client/client.js new file mode 100644 index 000000000..9eb9209f8 --- /dev/null +++ b/dist/client/client.js @@ -0,0 +1,119 @@ +"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 child_process_1 = require("child_process"); +var events_1 = require("events"); +var stream_1 = require("stream"); +var fs = require("fs"); +var path = require("path"); +var resolve = require("resolve"); +var byline = require("byline"); +var TypescriptServiceClient = (function (_super) { + __extends(TypescriptServiceClient, _super); + function TypescriptServiceClient(tsServerPath) { + var _this = _super.call(this) || this; + _this.callbacks = {}; + _this.seq = 0; + _this.onMessage = function (res) { + if (isResponse(res)) { + var callback = _this.callbacks[res.request_seq]; + if (callback) { + console.log("received response in", Date.now() - callback.started, "ms"); + delete _this.callbacks[res.request_seq]; + if (res.success) { + callback.resolve(res); + } + else { + callback.reject(new Error(res.message)); + } + } + } + else if (isEvent(res)) { + console.log("received event", res); + _this.emit(res.event, res.body); + } + }; + _this.tsServerPath = tsServerPath; + _this.serverPromise = _this.startServer(); + return _this; + } + TypescriptServiceClient.prototype.execute = function (command, args, expectResponse) { + var _this = this; + return this.serverPromise.then(function (cp) { + return _this.sendRequest(cp, command, args, expectResponse); + }).catch(function (err) { + console.log("command", command, "failed due to", err); + throw err; + }); + }; + TypescriptServiceClient.prototype.sendRequest = function (cp, command, args, expectResponse) { + var _this = this; + var req = { + seq: this.seq++, + command: command, + arguments: args + }; + var resultPromise = undefined; + if (expectResponse) { + resultPromise = new Promise(function (resolve, reject) { + _this.callbacks[req.seq] = { resolve: resolve, reject: reject, started: Date.now() }; + }); + } + cp.stdin.write(JSON.stringify(req) + "\n"); + return resultPromise; + }; + TypescriptServiceClient.prototype.startServer = function () { + var _this = this; + return new Promise(function (resolve, reject) { + console.log("starting", _this.tsServerPath); + var cp = child_process_1.spawn(_this.tsServerPath, []); + cp.once("error", function (err) { + console.log("tsserver starting failed with", err); + reject(err); + }); + cp.once("exit", function (code) { + console.log("tsserver failed to start with code", code); + reject({ code: code }); + }); + messageStream(cp.stdout).on("data", _this.onMessage); + _this.sendRequest(cp, "ping", null, true).then(function (res) { return resolve(cp); }, function (err) { return resolve(cp); }); + }); + }; + return TypescriptServiceClient; +}(events_1.EventEmitter)); +exports.TypescriptServiceClient = TypescriptServiceClient; +function isEvent(res) { + return res.type === "event"; +} +function isResponse(res) { + return res.type === "response"; +} +function findTSServer(basedir) { + var tsPath = resolve.sync("typescript", { basedir: basedir }); + var tsServerPath = path.resolve(path.dirname(tsPath), "..", "bin", "tsserver"); + fs.statSync(tsServerPath); + return tsServerPath; +} +exports.findTSServer = findTSServer; +function messageStream(input) { + return input.pipe(byline()).pipe(new MessageStream()); +} +var MessageStream = (function (_super) { + __extends(MessageStream, _super); + function MessageStream() { + var _this = _super.call(this, { objectMode: true }) || this; + _this.lineCount = 1; + return _this; + } + MessageStream.prototype._transform = function (line, encoding, callback) { + if (this.lineCount % 2 === 0) { + this.push(JSON.parse(line)); + } + this.lineCount += 1; + callback(null); + }; + return MessageStream; +}(stream_1.Transform)); diff --git a/dist/worker/lib/workerLib.js b/dist/worker/lib/workerLib.js index fbb629850..80292181e 100644 --- a/dist/worker/lib/workerLib.js +++ b/dist/worker/lib/workerLib.js @@ -165,7 +165,7 @@ var Parent = (function (_super) { stdio: ['ipc'] }); this.child.on('error', function (err) { - if (err.code === "ENOENT" && err.path === _this.node) { + if (err["code"] === "ENOENT" && err["path"] === _this.node) { _this.gotENOENTonSpawnNode = true; } console.log('CHILD ERR ONERROR:', err.message, err.stack, err); diff --git a/dist/worker/parent.js b/dist/worker/parent.js index 5191ee634..42a9ac73b 100644 --- a/dist/worker/parent.js +++ b/dist/worker/parent.js @@ -5,6 +5,7 @@ var exec = childprocess.exec; var spawn = childprocess.spawn; var workerLib = require("./lib/workerLib"); var atomConfig = require("../main/atom/atomConfig"); +var client_1 = require("../client/client"); var parent = new workerLib.Parent(); var mainPanel = require("../main/atom/views/mainPanelView"); parent.pendingRequestsChanged = function (pending) { @@ -81,3 +82,12 @@ exports.createProject = parent.sendToIpc(projectService.createProject); exports.toggleBreakpoint = parent.sendToIpc(projectService.toggleBreakpoint); var queryParent = require("./queryParent"); parent.registerAllFunctionsExportedFromAsResponders(queryParent); +var tsserverPath = client_1.findTSServer(__dirname); +var client = new client_1.TypescriptServiceClient(tsserverPath); +client.execute("open", { file: "hello.ts", fileContent: "let x = 'hello'; x", scriptKindName: "TS" }); +client.execute("completions", { file: "hello.ts", line: 1, offset: 18, prefix: "x" }, true).then(function (result) { + console.log("completions result", result); + client.execute("completions", { file: "hello.ts", line: 1, offset: 18, prefix: "x" }, true).then(function (result) { + console.log("more completions", result); + }); +}); diff --git a/lib/client/client.ts b/lib/client/client.ts new file mode 100644 index 000000000..cd9557edb --- /dev/null +++ b/lib/client/client.ts @@ -0,0 +1,153 @@ +import {ChildProcess, spawn} from "child_process" +import {EventEmitter} from "events" +import {Transform, Readable} from "stream" +import * as fs from "fs" +import * as path from "path" +import * as protocol from "typescript/lib/protocol" +import * as resolve from "resolve" +import byline = require("byline") + +export class TypescriptServiceClient extends EventEmitter { + + /** Map of callbacks that are waiting for responses */ + callbacks: { + [seq: number]: { + reject(res) + resolve(res) + started: number + } + } = {} + + /** Path to the tsserver executable */ + readonly tsServerPath: string + + /** The tsserver child process */ + server: ChildProcess + + /** Promise that resolves when the server is ready to accept requests */ + serverPromise: Promise + + private seq = 0 + + constructor(tsServerPath: string) { + super() + this.tsServerPath = tsServerPath + this.serverPromise = this.startServer() + } + + execute(command: protocol.CommandTypes.Completions, args: protocol.CompletionsRequestArgs, expectResponse: boolean): Promise + execute(command: protocol.CommandTypes.Open, args: protocol.OpenRequestArgs): void + execute(command: protocol.CommandTypes.Quickinfo, args: protocol.FileLocationRequestArgs, expectResponse: boolean): Promise + execute(command: string, args, expectResponse?: boolean): Promise { + return this.serverPromise.then(cp => { + return this.sendRequest(cp, command, args, expectResponse) + }).catch(err => { + console.log("command", command, "failed due to", err) + throw err + }) + } + + private onMessage = (res: protocol.Response | protocol.Event) => { + if (isResponse(res)) { + const callback = this.callbacks[res.request_seq] + if (callback) { + console.log("received response in", Date.now() - callback.started, "ms") + delete this.callbacks[res.request_seq] + if (res.success) { + callback.resolve(res) + } else { + callback.reject(new Error(res.message)) + } + } + } else if (isEvent(res)) { + console.log("received event", res) + this.emit(res.event, res.body) + } + } + + private sendRequest(cp: ChildProcess, command: string, args, expectResponse: boolean): Promise | undefined { + + const req = { + seq: this.seq++, + command, + arguments: args + } + + let resultPromise: Promise | undefined = undefined + + if (expectResponse) { + resultPromise = new Promise((resolve, reject) => { + this.callbacks[req.seq] = {resolve, reject, started: Date.now()} + }) + } + + cp.stdin.write(JSON.stringify(req) + "\n") + + return resultPromise + } + + private startServer(): Promise { + return new Promise((resolve, reject) => { + console.log("starting", this.tsServerPath) + + const cp = spawn(this.tsServerPath, []) + + cp.once("error", err => { + console.log("tsserver starting failed with", err) + reject(err) + }) + + cp.once("exit", code => { + console.log("tsserver failed to start with code", code) + reject({code}) + }) + + messageStream(cp.stdout).on("data", this.onMessage) + + // 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)) + }) + } +} + +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" +} + +/** Given a start directory, try to resolve tsserver executable from node_modules */ +export function findTSServer(basedir: string): string { + const tsPath = resolve.sync("typescript", {basedir}) + const tsServerPath = path.resolve(path.dirname(tsPath), "..", "bin", "tsserver") + + // This will throw if the file does not exist on the disk + fs.statSync(tsServerPath) + + return tsServerPath +} + +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 { + lineCount = 1 + + constructor() { + super({objectMode: true}) + } + + _transform(line, encoding, callback) { + if (this.lineCount % 2 === 0) { + this.push(JSON.parse(line)) + } + + this.lineCount += 1 + + callback(null) + } +} diff --git a/lib/tsconfig.json b/lib/tsconfig.json index c51fac6c1..c8baf796e 100644 --- a/lib/tsconfig.json +++ b/lib/tsconfig.json @@ -25,6 +25,7 @@ "!node_modules/**/*.tsx" ], "files": [ + "./client/client.ts", "./globals.ts", "./hyperclickProvider.ts", "./linter.ts", diff --git a/lib/worker/lib/workerLib.ts b/lib/worker/lib/workerLib.ts index d14d6c1bb..0e41fc05a 100644 --- a/lib/worker/lib/workerLib.ts +++ b/lib/worker/lib/workerLib.ts @@ -246,7 +246,7 @@ export class Parent extends RequesterResponder { }); this.child.on('error', (err) => { - if (err.code === "ENOENT" && err.path === this.node) { + if (err["code"] === "ENOENT" && err["path"] === this.node) { this.gotENOENTonSpawnNode = true; } console.log('CHILD ERR ONERROR:', err.message, err.stack, err); diff --git a/lib/worker/parent.ts b/lib/worker/parent.ts index 0102aded0..fa061b020 100644 --- a/lib/worker/parent.ts +++ b/lib/worker/parent.ts @@ -8,6 +8,8 @@ import workerLib = require('./lib/workerLib'); import tsconfig = require('../main/tsconfig/tsconfig'); import * as atomConfig from "../main/atom/atomConfig"; +import {TypescriptServiceClient, findTSServer} from "../client/client" + var parent = new workerLib.Parent(); import * as mainPanel from "../main/atom/views/mainPanelView"; parent.pendingRequestsChanged = (pending) => { @@ -104,3 +106,14 @@ export var toggleBreakpoint = parent.sendToIpc(projectService.toggleBreakpoint); // Automatically include all functions from "parentResponses" as responders import queryParent = require('./queryParent'); parent.registerAllFunctionsExportedFromAsResponders(queryParent); + +const tsserverPath = findTSServer(__dirname) +const client = new TypescriptServiceClient(tsserverPath) + +client.execute("open", {file: "hello.ts", fileContent: "let x = 'hello'; x", scriptKindName: "TS"}) +client.execute("completions", {file: "hello.ts", line: 1, offset: 18, prefix: "x"}, true).then(result => { + console.log("completions result", result) + client.execute("completions", {file: "hello.ts", line: 1, offset: 18, prefix: "x"}, true).then(result => { + console.log("more completions", result) + }) +}) diff --git a/package.json b/package.json index c8eb4f03d..3f09cf3da 100644 --- a/package.json +++ b/package.json @@ -50,10 +50,13 @@ "url": "https://github.com/TypeStrong/atom-typescript/issues" }, "dependencies": { + "@types/byline": "^4.2.31", + "@types/resolve": "0.0.4", "atom-package-deps": "^2.0.3", "atom-space-pen-views": "^2.0.4", "babel": "^5.6.23", "basarat-text-buffer": "6.0.0", + "byline": "^5.0.0", "byots": "2.2.0-dev.20161117.23.11", "d3": "^3.5.5", "detect-indent": "^4.0.0", @@ -68,6 +71,7 @@ "json2dts": "0.0.1", "mkdirp": "^0.5.0", "react": "^0.13.3", + "resolve": "1.1.7", "season": "^5.1.4", "tsconfig": "^2.2.0", "typescript": "2.2.0-dev.20161118", 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/typings.json b/typings.json index a1ded82c5..79cdcf0f0 100644 --- a/typings.json +++ b/typings.json @@ -4,8 +4,6 @@ "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" } } From 20d355241b61c5bc031677f6c80a5ef8768f4a0e Mon Sep 17 00:00:00 2001 From: Guntars Asmanis-Graham Date: Fri, 25 Nov 2016 20:52:31 -0500 Subject: [PATCH 03/70] Notify tsserver of open, change and close events --- dist/client/client.js | 33 ++++++++-- dist/main/atom/onSaveHandler.js | 31 --------- dist/main/atom/views/mainPanelView.js | 19 ------ dist/main/atomts.js | 52 +++++++-------- dist/worker/debug.js | 4 +- dist/worker/lib/workerLib.js | 3 + dist/worker/parent.js | 15 ++--- lib/client/client.ts | 42 +++++++++--- lib/main/atom/onSaveHandler.ts | 92 +++++++++++++-------------- lib/main/atom/views/mainPanelView.ts | 30 ++++----- lib/main/atomts.ts | 82 ++++++++++++++---------- lib/worker/debug.ts | 4 +- lib/worker/lib/workerLib.ts | 8 +++ lib/worker/parent.ts | 19 +++--- 14 files changed, 226 insertions(+), 208 deletions(-) diff --git a/dist/client/client.js b/dist/client/client.js index 9eb9209f8..064b02661 100644 --- a/dist/client/client.js +++ b/dist/client/client.js @@ -21,7 +21,7 @@ var TypescriptServiceClient = (function (_super) { if (isResponse(res)) { var callback = _this.callbacks[res.request_seq]; if (callback) { - console.log("received response in", Date.now() - callback.started, "ms"); + console.log("received response for", res.command, "in", Date.now() - callback.started, "ms", "with data", res.body); delete _this.callbacks[res.request_seq]; if (res.success) { callback.resolve(res); @@ -40,9 +40,28 @@ var TypescriptServiceClient = (function (_super) { _this.serverPromise = _this.startServer(); return _this; } - TypescriptServiceClient.prototype.execute = function (command, args, expectResponse) { + TypescriptServiceClient.prototype.executeChange = function (args) { + this.execute("change", args); + }; + TypescriptServiceClient.prototype.executeClose = function (args) { + this.execute("close", args); + }; + TypescriptServiceClient.prototype.executeCompletions = function (args) { + return this.execute("completions", args); + }; + TypescriptServiceClient.prototype.executeOpen = function (args) { + this.execute("open", args); + }; + TypescriptServiceClient.prototype.executeProjectInfo = function (args) { + return this.execute("projectInfo", args); + }; + TypescriptServiceClient.prototype.executeQuickInfo = function (args) { + return this.execute("quickInfo", args); + }; + TypescriptServiceClient.prototype.execute = function (command, args) { var _this = this; return this.serverPromise.then(function (cp) { + var expectResponse = !!TypescriptServiceClient.commandWithResponse[command]; return _this.sendRequest(cp, command, args, expectResponse); }).catch(function (err) { console.log("command", command, "failed due to", err); @@ -56,6 +75,7 @@ var TypescriptServiceClient = (function (_super) { command: command, arguments: args }; + console.log("sending request", command, "with args", args); var resultPromise = undefined; if (expectResponse) { resultPromise = new Promise(function (resolve, reject) { @@ -85,6 +105,11 @@ var TypescriptServiceClient = (function (_super) { return TypescriptServiceClient; }(events_1.EventEmitter)); exports.TypescriptServiceClient = TypescriptServiceClient; +TypescriptServiceClient.commandWithResponse = { + completions: true, + projectInfo: true, + quickInfo: true +}; function isEvent(res) { return res.type === "event"; } @@ -92,8 +117,8 @@ function isResponse(res) { return res.type === "response"; } function findTSServer(basedir) { - var tsPath = resolve.sync("typescript", { basedir: basedir }); - var tsServerPath = path.resolve(path.dirname(tsPath), "..", "bin", "tsserver"); + var tsPath = resolve.sync("typescript/package.json", { basedir: basedir }); + var tsServerPath = path.resolve(path.dirname(tsPath), "bin", "tsserver"); fs.statSync(tsServerPath); return tsServerPath; } diff --git a/dist/main/atom/onSaveHandler.js b/dist/main/atom/onSaveHandler.js index 03d0e4613..d2f131163 100644 --- a/dist/main/atom/onSaveHandler.js +++ b/dist/main/atom/onSaveHandler.js @@ -1,35 +1,4 @@ "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/views/mainPanelView.js b/dist/main/atom/views/mainPanelView.js index f67ae3637..90f6f1f47 100644 --- a/dist/main/atom/views/mainPanelView.js +++ b/dist/main/atom/views/mainPanelView.js @@ -10,7 +10,6 @@ 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', @@ -184,24 +183,6 @@ var MainPanelView = (function (_super) { } }; 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('
- ')); diff --git a/dist/main/atomts.js b/dist/main/atomts.js index 99faca211..76eb10959 100644 --- a/dist/main/atomts.js +++ b/dist/main/atomts.js @@ -9,7 +9,6 @@ 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"); @@ -48,11 +47,7 @@ function readyToActivate() { 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(''); - }); + updatePanelConfig(filePath); parent.errorsForFile({ filePath: filePath }) .then(function (resp) { mainPanelView_1.errorView.setErrors(filePath, resp.errors); @@ -69,6 +64,7 @@ function readyToActivate() { } }); editorWatch = atom.workspace.observeTextEditors(function (editor) { + console.log("opened editor", editor.getPath()); var editorView = atom_space_pen_views_1.$(atom.views.getView(editor)); tooltipManager.attach(editorView, editor); var filePath = editor.getPath(); @@ -77,11 +73,8 @@ function readyToActivate() { var isTst = ext === '.tst'; try { onlyOnceStuff(); - parent.getProjectFileDetails({ filePath: filePath }).then(function (res) { - mainPanelView.panelView.setTsconfigInUse(res.projectFilePath); - }).catch(function (err) { - mainPanelView.panelView.setTsconfigInUse(''); - }); + parent.client.executeOpen({ file: filePath }); + updatePanelConfig(filePath); var onDisk = false; if (fs.existsSync(filePath)) { onDisk = true; @@ -89,17 +82,6 @@ function readyToActivate() { 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 () { @@ -118,18 +100,22 @@ function readyToActivate() { }); 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 }); + parent.client.executeChange({ + endLine: diff.oldRange.end.row, + endOffset: diff.oldRange.end.column, + file: editor.getPath(), + line: diff.oldRange.start.row, + offset: diff.oldRange.start.column, + insertString: diff.newText, + }); }); var saveObserver = editor.onDidSave(function (event) { + console.log("saved", editor.getPath()); onDisk = true; filePath = event.path; - onSaveHandler.handle({ filePath: filePath, editor: editor }); }); var destroyObserver = editor.onDidDestroy(function () { + parent.client.executeClose({ file: editor.getPath() }); mainPanelView_1.errorView.setErrors(filePath, []); changeObserver.dispose(); fasterChangeObserver.dispose(); @@ -145,6 +131,16 @@ function readyToActivate() { }); commands.registerCommands(); } +function updatePanelConfig(file) { + parent.client.executeProjectInfo({ + needFileNameList: false, + file: file + }).then(function (result) { + mainPanelView.panelView.setTsconfigInUse(result.body.configFileName); + }, function (err) { + mainPanelView.panelView.setTsconfigInUse(''); + }); +} function activate(state) { require('atom-package-deps').install('atom-typescript').then(waitForGrammarActivation).then(readyToActivate); } diff --git a/dist/worker/debug.js b/dist/worker/debug.js index a77b0f234..8319ccdba 100644 --- a/dist/worker/debug.js +++ b/dist/worker/debug.js @@ -1,3 +1,3 @@ "use strict"; -exports.debugAll = false; -exports.debugSync = false || exports.debugAll; +exports.debugAll = true; +exports.debugSync = false; diff --git a/dist/worker/lib/workerLib.js b/dist/worker/lib/workerLib.js index 80292181e..351d1bc05 100644 --- a/dist/worker/lib/workerLib.js +++ b/dist/worker/lib/workerLib.js @@ -23,6 +23,7 @@ var RequesterResponder = (function () { this.pendingRequests = []; this.pendingRequestsChanged = function (pending) { return null; }; this.sendToIpcHeart = function (data, message) { + console.log("sending", message, "with", data); 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)); @@ -45,6 +46,7 @@ var RequesterResponder = (function () { return; } var message = parsed.message; + console.log("received", message, "with", parsed.data); var responsePromise; try { responsePromise = _this.responders[message](parsed.data); @@ -84,6 +86,7 @@ var RequesterResponder = (function () { console.log('PARENT ERR: No one was listening:', parsed.message, parsed.data); } else { + console.log("received", parsed.message, "with", parsed.data); if (parsed.error) { this.currentListeners[parsed.message][parsed.id].reject(parsed.error); console.log(parsed.error); diff --git a/dist/worker/parent.js b/dist/worker/parent.js index 42a9ac73b..742c309a8 100644 --- a/dist/worker/parent.js +++ b/dist/worker/parent.js @@ -3,6 +3,7 @@ var debug_1 = require("./debug"); var childprocess = require("child_process"); var exec = childprocess.exec; var spawn = childprocess.spawn; +var tsconfig = require("tsconfig"); var workerLib = require("./lib/workerLib"); var atomConfig = require("../main/atom/atomConfig"); var client_1 = require("../client/client"); @@ -63,7 +64,6 @@ exports.getSignatureHelps = catchCommonErrors(parent.sendToIpc(projectService.ge 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); @@ -83,11 +83,10 @@ exports.toggleBreakpoint = parent.sendToIpc(projectService.toggleBreakpoint); var queryParent = require("./queryParent"); parent.registerAllFunctionsExportedFromAsResponders(queryParent); var tsserverPath = client_1.findTSServer(__dirname); -var client = new client_1.TypescriptServiceClient(tsserverPath); -client.execute("open", { file: "hello.ts", fileContent: "let x = 'hello'; x", scriptKindName: "TS" }); -client.execute("completions", { file: "hello.ts", line: 1, offset: 18, prefix: "x" }, true).then(function (result) { - console.log("completions result", result); - client.execute("completions", { file: "hello.ts", line: 1, offset: 18, prefix: "x" }, true).then(function (result) { - console.log("more completions", result); +exports.client = new client_1.TypescriptServiceClient(tsserverPath); +function loadProjectConfig(sourcePath) { + return exports.client.executeProjectInfo({ needFileNameList: false, file: sourcePath }).then(function (result) { + return tsconfig.load(result.body.configFileName); }); -}); +} +exports.loadProjectConfig = loadProjectConfig; diff --git a/lib/client/client.ts b/lib/client/client.ts index cd9557edb..8e30d615f 100644 --- a/lib/client/client.ts +++ b/lib/client/client.ts @@ -3,7 +3,6 @@ import {EventEmitter} from "events" import {Transform, Readable} from "stream" import * as fs from "fs" import * as path from "path" -import * as protocol from "typescript/lib/protocol" import * as resolve from "resolve" import byline = require("byline") @@ -35,11 +34,34 @@ export class TypescriptServiceClient extends EventEmitter { this.serverPromise = this.startServer() } - execute(command: protocol.CommandTypes.Completions, args: protocol.CompletionsRequestArgs, expectResponse: boolean): Promise - execute(command: protocol.CommandTypes.Open, args: protocol.OpenRequestArgs): void - execute(command: protocol.CommandTypes.Quickinfo, args: protocol.FileLocationRequestArgs, expectResponse: boolean): Promise - execute(command: string, args, expectResponse?: boolean): Promise { + static commandWithResponse = { + completions: true, + projectInfo: true, + quickInfo: true + } + + executeChange(args: protocol.ChangeRequestArgs) { + this.execute("change", args) + } + executeClose(args: protocol.FileRequestArgs) { + this.execute("close", args) + } + executeCompletions(args: protocol.CompletionsRequestArgs): Promise { + return this.execute("completions", args) + } + executeOpen(args: protocol.OpenRequestArgs) { + this.execute("open", args) + } + executeProjectInfo(args: protocol.ProjectInfoRequestArgs): Promise { + return this.execute("projectInfo", args) + } + executeQuickInfo(args: protocol.FileLocationRequestArgs): Promise { + return this.execute("quickInfo", args) + } + + execute(command: string, args): Promise { return this.serverPromise.then(cp => { + const expectResponse = !!TypescriptServiceClient.commandWithResponse[command] return this.sendRequest(cp, command, args, expectResponse) }).catch(err => { console.log("command", command, "failed due to", err) @@ -51,7 +73,7 @@ export class TypescriptServiceClient extends EventEmitter { if (isResponse(res)) { const callback = this.callbacks[res.request_seq] if (callback) { - console.log("received response in", Date.now() - callback.started, "ms") + console.log("received response for", res.command, "in", Date.now() - callback.started, "ms", "with data", res.body) delete this.callbacks[res.request_seq] if (res.success) { callback.resolve(res) @@ -73,6 +95,8 @@ export class TypescriptServiceClient extends EventEmitter { arguments: args } + console.log("sending request", command, "with args", args) + let resultPromise: Promise | undefined = undefined if (expectResponse) { @@ -104,7 +128,7 @@ export class TypescriptServiceClient extends EventEmitter { messageStream(cp.stdout).on("data", this.onMessage) - // We send an unknown command to verify that the server is working. + // 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)) }) } @@ -120,8 +144,8 @@ function isResponse(res: protocol.Response | protocol.Event): res is protocol.Re /** Given a start directory, try to resolve tsserver executable from node_modules */ export function findTSServer(basedir: string): string { - const tsPath = resolve.sync("typescript", {basedir}) - const tsServerPath = path.resolve(path.dirname(tsPath), "..", "bin", "tsserver") + const tsPath = resolve.sync("typescript/package.json", {basedir}) + const tsServerPath = path.resolve(path.dirname(tsPath), "bin", "tsserver") // This will throw if the file does not exist on the disk fs.statSync(tsServerPath) diff --git a/lib/main/atom/onSaveHandler.ts b/lib/main/atom/onSaveHandler.ts index 16e8cde77..fa993a4dd 100644 --- a/lib/main/atom/onSaveHandler.ts +++ b/lib/main/atom/onSaveHandler.ts @@ -14,51 +14,51 @@ import {getFileStatus} from "./fileStatusCache"; 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() }); + // // 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(); - // 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'); - } - - }); + // Compile on save TODO: Restore this functionality + // 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/views/mainPanelView.ts b/lib/main/atom/views/mainPanelView.ts index eb2584ae9..e9cc7a9d7 100644 --- a/lib/main/atom/views/mainPanelView.ts +++ b/lib/main/atom/views/mainPanelView.ts @@ -214,21 +214,21 @@ export class MainPanelView extends view.View { ///////////// 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'); - } - } - }); + // 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 diff --git a/lib/main/atomts.ts b/lib/main/atomts.ts index 5a53d5b15..60a45c583 100644 --- a/lib/main/atomts.ts +++ b/lib/main/atomts.ts @@ -105,11 +105,7 @@ function readyToActivate() { var filePath = editor.getPath(); onlyOnceStuff(); - parent.getProjectFileDetails({filePath}).then((res)=>{ - mainPanelView.panelView.setTsconfigInUse(res.projectFilePath); - }).catch(err=>{ - mainPanelView.panelView.setTsconfigInUse(''); - }); + updatePanelConfig(filePath); // Refresh errors stuff on change active tab. // Because the fix might be in the other file @@ -134,6 +130,8 @@ function readyToActivate() { // Observe editors loading editorWatch = atom.workspace.observeTextEditors((editor: AtomCore.IEditor) => { + console.log("opened editor", editor.getPath()) + // subscribe for tooltips // inspiration : https://github.com/chaika2013/ide-haskell var editorView = $(atom.views.getView(editor)); @@ -146,11 +144,10 @@ function readyToActivate() { try { // Only once stuff onlyOnceStuff(); - parent.getProjectFileDetails({filePath}).then((res)=>{ - mainPanelView.panelView.setTsconfigInUse(res.projectFilePath); - }).catch(err=>{ - mainPanelView.panelView.setTsconfigInUse(''); - }); + + parent.client.executeOpen({file: filePath}) + + updatePanelConfig(filePath); // We only do analysis once the file is persisted to disk var onDisk = false; @@ -165,22 +162,22 @@ function readyToActivate() { 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); - } - }); + // // 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 @@ -233,14 +230,14 @@ function readyToActivate() { //// 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 }); + parent.client.executeChange({ + endLine: diff.oldRange.end.row, + endOffset: diff.oldRange.end.column, + file: editor.getPath(), + line: diff.oldRange.start.row, + offset: diff.oldRange.start.column, + insertString: diff.newText, + }) // For debugging the language service going out of sync // console.log(JSON.stringify({oldText,newText})); @@ -256,14 +253,17 @@ function readyToActivate() { // Observe editors saving var saveObserver = editor.onDidSave((event) => { + console.log("saved", editor.getPath()) 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 }); + // onSaveHandler.handle({ filePath: filePath, editor: editor }); }); // Observe editors closing var destroyObserver = editor.onDidDestroy(() => { + parent.client.executeClose({file: editor.getPath()}) + // Clear errors in view errorView.setErrors(filePath, []); @@ -285,6 +285,18 @@ function readyToActivate() { commands.registerCommands(); } +/** Update the panel with the configu resolved from the given source file */ +function updatePanelConfig(file: string) { + parent.client.executeProjectInfo({ + needFileNameList: false, + file + }).then(result => { + mainPanelView.panelView.setTsconfigInUse(result.body.configFileName) + }, err => { + mainPanelView.panelView.setTsconfigInUse(''); + }) +} + export function activate(state: PackageState) { require('atom-package-deps').install('atom-typescript').then(waitForGrammarActivation).then(readyToActivate) } diff --git a/lib/worker/debug.ts b/lib/worker/debug.ts index 281133b15..cb522f8e6 100644 --- a/lib/worker/debug.ts +++ b/lib/worker/debug.ts @@ -1,5 +1,5 @@ /** Set this to true if you want to debug all things */ -export var debugAll = false; +export var debugAll = true; /** 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; +export var debugSync = false; diff --git a/lib/worker/lib/workerLib.ts b/lib/worker/lib/workerLib.ts index 0e41fc05a..8633144e8 100644 --- a/lib/worker/lib/workerLib.ts +++ b/lib/worker/lib/workerLib.ts @@ -69,6 +69,9 @@ class RequesterResponder { console.log('PARENT ERR: No one was listening:', parsed.message, parsed.data); } else { // Alright nothing *weird* happened + + console.log("received", parsed.message, "with", parsed.data) + if (parsed.error) { this.currentListeners[parsed.message][parsed.id].reject(parsed.error); console.log(parsed.error); @@ -91,6 +94,8 @@ class RequesterResponder { private sendToIpcHeart = (data, message) => { + console.log("sending", message, "with", data) + // If we don't have a child exit if (!this.getProcess()) { console.log('PARENT ERR: no child when you tried to send :', message); @@ -176,6 +181,9 @@ class RequesterResponder { return; } var message = parsed.message; + + console.log("received", message, "with", parsed.data) + var responsePromise: Promise; try { responsePromise = this.responders[message](parsed.data); diff --git a/lib/worker/parent.ts b/lib/worker/parent.ts index fa061b020..dbc20078f 100644 --- a/lib/worker/parent.ts +++ b/lib/worker/parent.ts @@ -4,8 +4,11 @@ import childprocess = require('child_process'); var exec = childprocess.exec; var spawn = childprocess.spawn; +import * as path from "path" +import * as tsconfig from "tsconfig" + import workerLib = require('./lib/workerLib'); -import tsconfig = require('../main/tsconfig/tsconfig'); +import * as protocol from "typescript/lib/protocol"; import * as atomConfig from "../main/atom/atomConfig"; import {TypescriptServiceClient, findTSServer} from "../client/client" @@ -85,7 +88,7 @@ export var getSignatureHelps = catchCommonErrors(parent.sendToIpc(projectService 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); @@ -108,12 +111,10 @@ import queryParent = require('./queryParent'); parent.registerAllFunctionsExportedFromAsResponders(queryParent); const tsserverPath = findTSServer(__dirname) -const client = new TypescriptServiceClient(tsserverPath) +export const client = new TypescriptServiceClient(tsserverPath) -client.execute("open", {file: "hello.ts", fileContent: "let x = 'hello'; x", scriptKindName: "TS"}) -client.execute("completions", {file: "hello.ts", line: 1, offset: 18, prefix: "x"}, true).then(result => { - console.log("completions result", result) - client.execute("completions", {file: "hello.ts", line: 1, offset: 18, prefix: "x"}, true).then(result => { - console.log("more completions", result) +export function loadProjectConfig(sourcePath: string): Promise { + return client.executeProjectInfo({needFileNameList: false, file: sourcePath}).then(result => { + return tsconfig.load(result.body.configFileName) }) -}) +} From 50e884c14e3322c6b1fe708f050127366f8dd8f2 Mon Sep 17 00:00:00 2001 From: Guntars Asmanis-Graham Date: Sat, 26 Nov 2016 00:42:13 -0500 Subject: [PATCH 04/70] Use errors from tsserver --- dist/client/client.js | 42 +- dist/main/atomts.js | 48 +- lib/client/client.ts | 33 +- lib/main/atomts.ts | 80 +- lib/tsconfig.json | 1 - lib/typings/atom/atom.d.ts | 1759 ------------------------------------ lib/typings/tsd.d.ts | 1 - package.json | 1 + 8 files changed, 142 insertions(+), 1823 deletions(-) delete mode 100644 lib/typings/atom/atom.d.ts diff --git a/dist/client/client.js b/dist/client/client.js index 064b02661..bc418a10b 100644 --- a/dist/client/client.js +++ b/dist/client/client.js @@ -5,19 +5,18 @@ var __extends = (this && this.__extends) || function (d, b) { d.prototype = b === null ? Object.create(b) : (__.prototype = b.prototype, new __()); }; var child_process_1 = require("child_process"); -var events_1 = require("events"); var stream_1 = require("stream"); var fs = require("fs"); var path = require("path"); var resolve = require("resolve"); var byline = require("byline"); -var TypescriptServiceClient = (function (_super) { - __extends(TypescriptServiceClient, _super); +var TypescriptServiceClient = (function () { function TypescriptServiceClient(tsServerPath) { - var _this = _super.call(this) || this; - _this.callbacks = {}; - _this.seq = 0; - _this.onMessage = function (res) { + var _this = this; + this.callbacks = {}; + this.listeners = {}; + this.seq = 0; + this.onMessage = function (res) { if (isResponse(res)) { var callback = _this.callbacks[res.request_seq]; if (callback) { @@ -33,12 +32,17 @@ var TypescriptServiceClient = (function (_super) { } else if (isEvent(res)) { console.log("received event", res); - _this.emit(res.event, res.body); + var listeners = _this.listeners[res.event]; + if (listeners) { + for (var _i = 0, listeners_1 = listeners; _i < listeners_1.length; _i++) { + var listener = listeners_1[_i]; + listener(res.body); + } + } } }; - _this.tsServerPath = tsServerPath; - _this.serverPromise = _this.startServer(); - return _this; + this.tsServerPath = tsServerPath; + this.serverPromise = this.startServer(); } TypescriptServiceClient.prototype.executeChange = function (args) { this.execute("change", args); @@ -49,6 +53,9 @@ var TypescriptServiceClient = (function (_super) { TypescriptServiceClient.prototype.executeCompletions = function (args) { return this.execute("completions", args); }; + TypescriptServiceClient.prototype.executeGetErr = function (args) { + this.execute("geterr", args); + }; TypescriptServiceClient.prototype.executeOpen = function (args) { this.execute("open", args); }; @@ -68,6 +75,17 @@ var TypescriptServiceClient = (function (_super) { throw err; }); }; + TypescriptServiceClient.prototype.on = function (name, listener) { + var _this = this; + if (this.listeners[name] === undefined) { + this.listeners[name] = []; + } + this.listeners[name].push(listener); + return function () { + var idx = _this.listeners[name].indexOf(listener); + _this.listeners[name].splice(idx, 1); + }; + }; TypescriptServiceClient.prototype.sendRequest = function (cp, command, args, expectResponse) { var _this = this; var req = { @@ -103,7 +121,7 @@ var TypescriptServiceClient = (function (_super) { }); }; return TypescriptServiceClient; -}(events_1.EventEmitter)); +}()); exports.TypescriptServiceClient = TypescriptServiceClient; TypescriptServiceClient.commandWithResponse = { completions: true, diff --git a/dist/main/atomts.js b/dist/main/atomts.js index 76eb10959..df97272c4 100644 --- a/dist/main/atomts.js +++ b/dist/main/atomts.js @@ -10,6 +10,7 @@ var tooltipManager = require("./atom/tooltipManager"); var atomUtils = require("./atom/atomUtils"); var commands = require("./atom/commands/commands"); var debugAtomTs = require("./atom/debugAtomTs"); +var _atom = require("atom"); var atom_space_pen_views_1 = require("atom-space-pen-views"); var documentationView = require("./atom/views/documentationView"); var renameView = require("./atom/views/renameView"); @@ -64,10 +65,28 @@ function readyToActivate() { } }); editorWatch = atom.workspace.observeTextEditors(function (editor) { - console.log("opened editor", editor.getPath()); + var filePath = editor.getPath(); + console.log("opened editor", filePath); var editorView = atom_space_pen_views_1.$(atom.views.getView(editor)); tooltipManager.attach(editorView, editor); - var filePath = editor.getPath(); + var unsubSyntax = parent.client.on("syntaxDiag", function (diag) { + console.log("syntax errors", diag); + }); + var unsubSemantic = parent.client.on("semanticDiag", function (diag) { + console.log("semantic errors", diag); + if (diag.file === filePath) { + mainPanelView_1.errorView.setErrors(filePath, diag.diagnostics.map(function (error) { + var preview = editor.buffer.getTextInRange(new _atom.Range([error.start.line - 1, error.start.offset - 1], [error.end.line - 1, error.end.offset - 1])); + return { + filePath: filePath, + startPos: { line: error.start.line - 1, col: error.start.offset - 1 }, + endPos: { line: error.end.line - 1, col: error.end.offset - 1 }, + message: ts.flattenDiagnosticMessageText(error.text, '\n'), + preview: preview + }; + })); + } + }); var ext = path.extname(filePath); if (atomUtils.isAllowedExtension(ext)) { var isTst = ext === '.tst'; @@ -82,6 +101,7 @@ function readyToActivate() { hideIfNotActiveOnStart(); debugAtomTs.runDebugCode({ filePath: filePath, editor: editor }); if (onDisk) { + parent.client.executeGetErr({ files: [filePath], delay: 100 }); } editorSetup.setupEditor(editor); var changeObserver = editor.onDidStopChanging(function () { @@ -95,8 +115,7 @@ function readyToActivate() { mainPanelView_1.errorView.setErrors(filePath, [{ startPos: root, endPos: root, filePath: filePath, message: "Please save file for it be processed by TypeScript", preview: "" }]); return; } - parent.errorsForFile({ filePath: filePath }) - .then(function (resp) { return mainPanelView_1.errorView.setErrors(filePath, resp.errors); }); + parent.client.executeGetErr({ files: [filePath], delay: 100 }); }); var buffer = editor.buffer; var fasterChangeObserver = editor.buffer.onDidChange(function (diff) { @@ -121,6 +140,8 @@ function readyToActivate() { fasterChangeObserver.dispose(); saveObserver.dispose(); destroyObserver.dispose(); + unsubSemantic(); + unsubSyntax(); }); } catch (ex) { @@ -142,7 +163,7 @@ function updatePanelConfig(file) { }); } function activate(state) { - require('atom-package-deps').install('atom-typescript').then(waitForGrammarActivation).then(readyToActivate); + require('atom-package-deps').install('atom-typescript').then(readyToActivate); } exports.activate = activate; function deactivate() { @@ -175,23 +196,6 @@ function consumeSnippets(snippetsManager) { atomUtils._setSnippetsManager(snippetsManager); } 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(); - } - }); - }); - }); - return promise; -} var hyperclickProvider = require("../hyperclickProvider"); function getHyperclickProvider() { return hyperclickProvider; diff --git a/lib/client/client.ts b/lib/client/client.ts index 8e30d615f..c6c844db4 100644 --- a/lib/client/client.ts +++ b/lib/client/client.ts @@ -6,7 +6,7 @@ import * as path from "path" import * as resolve from "resolve" import byline = require("byline") -export class TypescriptServiceClient extends EventEmitter { +export class TypescriptServiceClient { /** Map of callbacks that are waiting for responses */ callbacks: { @@ -17,6 +17,10 @@ export class TypescriptServiceClient extends EventEmitter { } } = {} + private listeners: { + [event: string]: ((event: any) => any)[] + } = {} + /** Path to the tsserver executable */ readonly tsServerPath: string @@ -29,7 +33,6 @@ export class TypescriptServiceClient extends EventEmitter { private seq = 0 constructor(tsServerPath: string) { - super() this.tsServerPath = tsServerPath this.serverPromise = this.startServer() } @@ -49,6 +52,9 @@ export class TypescriptServiceClient extends EventEmitter { executeCompletions(args: protocol.CompletionsRequestArgs): Promise { return this.execute("completions", args) } + executeGetErr(args: protocol.GeterrRequestArgs) { + this.execute("geterr", args) + } executeOpen(args: protocol.OpenRequestArgs) { this.execute("open", args) } @@ -69,6 +75,22 @@ export class TypescriptServiceClient extends EventEmitter { }) } + /** Adds an event listener for tsserver events. Returns an unsubscribe function */ + on(name: "syntaxDiag", listener: (result: protocol.DiagnosticEventBody) => any): Function + on(name: "semanticDiag", listener: (result: protocol.DiagnosticEventBody) => any): Function + on(name: string, listener: (result: any) => any): Function { + if (this.listeners[name] === undefined) { + this.listeners[name] = [] + } + + this.listeners[name].push(listener) + + return () => { + const idx = this.listeners[name].indexOf(listener) + this.listeners[name].splice(idx, 1) + } + } + private onMessage = (res: protocol.Response | protocol.Event) => { if (isResponse(res)) { const callback = this.callbacks[res.request_seq] @@ -83,7 +105,12 @@ export class TypescriptServiceClient extends EventEmitter { } } else if (isEvent(res)) { console.log("received event", res) - this.emit(res.event, res.body) + const listeners = this.listeners[res.event] + if (listeners) { + for (const listener of listeners) { + listener(res.body) + } + } } } diff --git a/lib/main/atomts.ts b/lib/main/atomts.ts index 60a45c583..a6fe468c9 100644 --- a/lib/main/atomts.ts +++ b/lib/main/atomts.ts @@ -129,15 +129,41 @@ function readyToActivate() { // Observe editors loading editorWatch = atom.workspace.observeTextEditors((editor: AtomCore.IEditor) => { + let filePath = editor.getPath() - console.log("opened editor", editor.getPath()) + console.log("opened editor", filePath) // subscribe for tooltips // inspiration : https://github.com/chaika2013/ide-haskell - var editorView = $(atom.views.getView(editor)); - tooltipManager.attach(editorView, editor); + var editorView = $(atom.views.getView(editor)) + tooltipManager.attach(editorView, editor) + + // Listen for error events for this file and display them + const unsubSyntax = parent.client.on("syntaxDiag", diag => { + console.log("syntax errors", diag) + }) + + const unsubSemantic = parent.client.on("semanticDiag", diag => { + console.log("semantic errors", diag) + + if (diag.file === filePath) { + errorView.setErrors(filePath, diag.diagnostics.map(error => { + const preview = editor.buffer.getTextInRange( + new _atom.Range( + [error.start.line-1, error.start.offset-1], + [error.end.line-1, error.end.offset-1])) + + return { + filePath: filePath, + startPos: {line: error.start.line - 1, col: error.start.offset - 1}, + endPos: {line: error.end.line - 1, col: error.end.offset - 1}, + message: ts.flattenDiagnosticMessageText(error.text, '\n'), + preview + } + })) + } + }) - var filePath = editor.getPath(); var ext = path.extname(filePath); if (atomUtils.isAllowedExtension(ext)) { let isTst = ext === '.tst'; @@ -162,6 +188,8 @@ function readyToActivate() { if (onDisk) { + parent.client.executeGetErr({files: [filePath], delay: 100}) + // // Set errors in project per file // parent.updateText({ filePath: filePath, text: editor.getText() }) // .then(() => parent.errorsForFile({ filePath: filePath })) @@ -204,8 +232,7 @@ function readyToActivate() { } // Set errors in project per file - parent.errorsForFile({ filePath: filePath }) - .then((resp) => errorView.setErrors(filePath, resp.errors)); + parent.client.executeGetErr({files: [filePath], delay: 100}) // TODO: provide function completions /*var position = atomUtils.getEditorPosition(editor); @@ -272,6 +299,9 @@ function readyToActivate() { fasterChangeObserver.dispose(); saveObserver.dispose(); destroyObserver.dispose(); + + unsubSemantic() + unsubSyntax() }); } catch (ex) { @@ -298,7 +328,7 @@ function updatePanelConfig(file: string) { } export function activate(state: PackageState) { - require('atom-package-deps').install('atom-typescript').then(waitForGrammarActivation).then(readyToActivate) + require('atom-package-deps').install('atom-typescript').then(readyToActivate) } export function deactivate() { @@ -331,24 +361,24 @@ export function consumeSnippets(snippetsManager) { atomUtils._setSnippetsManager(snippetsManager); } -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; -} +// 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; +// } import * as hyperclickProvider from "../hyperclickProvider"; export function getHyperclickProvider() { diff --git a/lib/tsconfig.json b/lib/tsconfig.json index c8baf796e..c73ebf175 100644 --- a/lib/tsconfig.json +++ b/lib/tsconfig.json @@ -107,7 +107,6 @@ "./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", 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/tsd.d.ts b/lib/typings/tsd.d.ts index 47917ffd9..a13240feb 100644 --- a/lib/typings/tsd.d.ts +++ b/lib/typings/tsd.d.ts @@ -1,6 +1,5 @@ /// /// -/// /// /// /// diff --git a/package.json b/package.json index 3f09cf3da..12cbc0ba3 100644 --- a/package.json +++ b/package.json @@ -50,6 +50,7 @@ "url": "https://github.com/TypeStrong/atom-typescript/issues" }, "dependencies": { + "@types/atom": "0.0.35", "@types/byline": "^4.2.31", "@types/resolve": "0.0.4", "atom-package-deps": "^2.0.3", From 053d1902eefc9c6fea9d368581b14a6dac958f04 Mon Sep 17 00:00:00 2001 From: Guntars Asmanis-Graham Date: Sat, 26 Nov 2016 17:56:40 -0500 Subject: [PATCH 05/70] Update some typings --- dist/client/client.js | 2 +- dist/linter.js | 1 + dist/main/atom/atomUtils.js | 2 +- dist/main/atom/views/mainPanelView.js | 13 +- dist/main/atom/views/renameView.js | 2 +- dist/main/atomts.js | 5 - dist/main/lang/core/languageServiceHost2.js | 4 +- dist/worker/parent.js | 3 - lib/linter.ts | 2 + lib/main/atom/atomConfig.ts | 2 +- lib/main/atom/atomUtils.ts | 4 +- lib/main/atom/views/mainPanelView.ts | 27 +- lib/main/atom/views/renameView.ts | 6 +- lib/main/atomts.ts | 16 +- lib/main/lang/core/languageServiceHost2.ts | 10 +- lib/tsconfig.json | 120 - lib/typings/emissary/emissary.d.ts | 2 - lib/typings/jquery/jquery.d.ts | 3185 ------------------- lib/typings/mixto/mixto.d.ts | 16 - lib/typings/space-pen/space-pen.d.ts | 625 ---- lib/typings/status-bar/status-bar.d.ts | 32 - lib/typings/text-buffer/text-buffer.d.ts | 305 -- lib/typings/tsd.d.ts | 5 - lib/worker/parent.ts | 4 - 24 files changed, 41 insertions(+), 4352 deletions(-) delete mode 100644 lib/typings/jquery/jquery.d.ts delete mode 100644 lib/typings/mixto/mixto.d.ts delete mode 100644 lib/typings/space-pen/space-pen.d.ts delete mode 100644 lib/typings/status-bar/status-bar.d.ts delete mode 100644 lib/typings/text-buffer/text-buffer.d.ts diff --git a/dist/client/client.js b/dist/client/client.js index bc418a10b..827d433db 100644 --- a/dist/client/client.js +++ b/dist/client/client.js @@ -122,12 +122,12 @@ var TypescriptServiceClient = (function () { }; return TypescriptServiceClient; }()); -exports.TypescriptServiceClient = TypescriptServiceClient; TypescriptServiceClient.commandWithResponse = { completions: true, projectInfo: true, quickInfo: true }; +exports.TypescriptServiceClient = TypescriptServiceClient; function isEvent(res) { return res.type === "event"; } diff --git a/dist/linter.js b/dist/linter.js index 983923adc..6629797a4 100644 --- a/dist/linter.js +++ b/dist/linter.js @@ -8,6 +8,7 @@ exports.provider = { scope: 'file', lintOnFly: true, lint: function (textEditor) { + console.log("lint called"); if (!textEditor.buffer.file || !textEditor.buffer.file.path || !fs.existsSync(textEditor.buffer.file.path)) diff --git a/dist/main/atom/atomUtils.js b/dist/main/atom/atomUtils.js index 7c9eb3896..01e5bfc90 100644 --- a/dist/main/atom/atomUtils.js +++ b/dist/main/atom/atomUtils.js @@ -207,7 +207,7 @@ function registerOpener(config) { 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()); }); diff --git a/dist/main/atom/views/mainPanelView.js b/dist/main/atom/views/mainPanelView.js index 90f6f1f47..a68b017e8 100644 --- a/dist/main/atom/views/mainPanelView.js +++ b/dist/main/atom/views/mainPanelView.js @@ -8,7 +8,6 @@ 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 panelHeaders = { error: 'Errors In Open Files', @@ -151,17 +150,7 @@ var MainPanelView = (function (_super) { 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); }); - } + console.log("soft reset"); }; MainPanelView.prototype.setTsconfigInUse = function (tsconfigFilePath) { this.fullTsconfigPath = tsconfigFilePath; diff --git a/dist/main/atom/views/renameView.js b/dist/main/atom/views/renameView.js index 9c3bc3bd0..06b4367ef 100644 --- a/dist/main/atom/views/renameView.js +++ b/dist/main/atom/views/renameView.js @@ -65,7 +65,7 @@ var RenameView = (function (_super) { this.newNameEditor.model.selectAll(); } else { - this.newNameEditor.model.moveToEndOfScreenLine(); + this.newNameEditor.model.moveCursorToEndOfScreenLine(); } this.title.text(this.options.title); this.newNameEditor.focus(); diff --git a/dist/main/atomts.js b/dist/main/atomts.js index df97272c4..7c056ffbf 100644 --- a/dist/main/atomts.js +++ b/dist/main/atomts.js @@ -49,11 +49,6 @@ function readyToActivate() { var filePath = editor.getPath(); onlyOnceStuff(); updatePanelConfig(filePath); - parent.errorsForFile({ filePath: filePath }) - .then(function (resp) { - mainPanelView_1.errorView.setErrors(filePath, resp.errors); - atomUtils.triggerLinter(); - }); mainPanelView.panelView.updateFileStatus(filePath); mainPanelView.show(); } diff --git a/dist/main/lang/core/languageServiceHost2.js b/dist/main/lang/core/languageServiceHost2.js index 074153b6a..e124b343d 100644 --- a/dist/main/lang/core/languageServiceHost2.js +++ b/dist/main/lang/core/languageServiceHost2.js @@ -1,7 +1,7 @@ "use strict"; -var path = require("path"); var fs = require("fs"); var os = require("os"); +var path = require("path"); var textBuffer = require("basarat-text-buffer"); var typescriptServices_1 = require("../typescriptServices"); function createScriptInfo(fileName, text, isOpen) { @@ -33,7 +33,7 @@ function createScriptInfo(fileName, text, isOpen) { 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 }); + buffer.setTextInRange([[start.line, start.col], [end.line, end.col]], newText, false); _lineStartIsDirty = true; editRanges.push({ span: { start: minChar, length: limChar - minChar }, diff --git a/dist/worker/parent.js b/dist/worker/parent.js index 742c309a8..53aaa948c 100644 --- a/dist/worker/parent.js +++ b/dist/worker/parent.js @@ -1,8 +1,5 @@ "use strict"; var debug_1 = require("./debug"); -var childprocess = require("child_process"); -var exec = childprocess.exec; -var spawn = childprocess.spawn; var tsconfig = require("tsconfig"); var workerLib = require("./lib/workerLib"); var atomConfig = require("../main/atom/atomConfig"); diff --git a/lib/linter.ts b/lib/linter.ts index 9f3f2e249..05997222a 100644 --- a/lib/linter.ts +++ b/lib/linter.ts @@ -25,6 +25,8 @@ export var provider = { lintOnFly: true, // # must be false for scope: 'project' lint: (textEditor: AtomCore.IEditor): Promise => { + console.log("lint called") + // We do not support files not on disk if (!textEditor.buffer.file || !textEditor.buffer.file.path diff --git a/lib/main/atom/atomConfig.ts b/lib/main/atom/atomConfig.ts index 413f52813..c9525a5cd 100644 --- a/lib/main/atom/atomConfig.ts +++ b/lib/main/atom/atomConfig.ts @@ -10,7 +10,7 @@ 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); + return (atom.config as any).set(packageName + '.' + getName(nameLambda), value); } class Config { diff --git a/lib/main/atom/atomUtils.ts b/lib/main/atom/atomUtils.ts index 83f238e0c..e50ab1cfd 100644 --- a/lib/main/atom/atomUtils.ts +++ b/lib/main/atom/atomUtils.ts @@ -1,5 +1,3 @@ - - import path = require('path'); import fs = require('fs'); import * as fsu from "../utils/fsUtil"; @@ -246,7 +244,7 @@ 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()); diff --git a/lib/main/atom/views/mainPanelView.ts b/lib/main/atom/views/mainPanelView.ts index e9cc7a9d7..2cc8f77d2 100644 --- a/lib/main/atom/views/mainPanelView.ts +++ b/lib/main/atom/views/mainPanelView.ts @@ -175,19 +175,20 @@ export class MainPanelView extends view.View { } 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)); - } + console.log("soft reset") + // 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 diff --git a/lib/main/atom/views/renameView.ts b/lib/main/atom/views/renameView.ts index 37c2ca5d3..4b66770f1 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; } @@ -21,7 +21,7 @@ interface RenameViewOptions { export class RenameView extends view.View { - private newNameEditor: EditorView; + private newNameEditor: EditorViewzz; private validationMessage: JQuery; private fileCount: JQuery; private title: JQuery; @@ -83,7 +83,7 @@ export class RenameView this.newNameEditor.model.selectAll(); } else { - this.newNameEditor.model.moveToEndOfScreenLine(); + this.newNameEditor.model.moveCursorToEndOfScreenLine(); } this.title.text(this.options.title); this.newNameEditor.focus(); diff --git a/lib/main/atomts.ts b/lib/main/atomts.ts index a6fe468c9..303affede 100644 --- a/lib/main/atomts.ts +++ b/lib/main/atomts.ts @@ -107,14 +107,14 @@ function readyToActivate() { onlyOnceStuff(); updatePanelConfig(filePath); - // 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(); - }); + // // 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(); diff --git a/lib/main/lang/core/languageServiceHost2.ts b/lib/main/lang/core/languageServiceHost2.ts index 6dcc7a985..4e2b22877 100644 --- a/lib/main/lang/core/languageServiceHost2.ts +++ b/lib/main/lang/core/languageServiceHost2.ts @@ -1,12 +1,13 @@ -import path = require('path'); -import utils = require('../utils'); import fs = require('fs'); import os = require('os') +import path = require('path'); import textBuffer = require('basarat-text-buffer'); +import utils = require('../utils'); import tsconfig = require('../../tsconfig/tsconfig'); import {typescriptServices} from "../typescriptServices"; + interface ScriptInfo { getFileName(): string; getContent(): string; @@ -16,7 +17,6 @@ interface ScriptInfo { getEditRanges(): ts.TextChangeRange[]; getLineStarts(): number[]; - updateContent(newContent: string): void; editContent(minChar: number, limChar: number, newText: string): void; getPositionFromLine(line: number, ch: number): number; @@ -82,7 +82,7 @@ function createScriptInfo(fileName: string, text: string, isOpen = false): Scrip // 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}); + buffer.setTextInRange([[start.line, start.col], [end.line, end.col]] as any, newText, false); // console.error(buffer.getText().length); // console.error(JSON.stringify({newText, final:buffer.getText()})); @@ -107,7 +107,7 @@ function createScriptInfo(fileName: string, text: string, isOpen = false): Scrip * @param character charecter poisiton in the line */ function getPositionFromLine(line: number, ch: number) { - return buffer.characterIndexForPosition([line, ch]); + return buffer.characterIndexForPosition([line, ch] as any); } /** diff --git a/lib/tsconfig.json b/lib/tsconfig.json index c73ebf175..ee5b51c68 100644 --- a/lib/tsconfig.json +++ b/lib/tsconfig.json @@ -17,127 +17,7 @@ "dts": { "name": "atom-typescript" }, - "filesGlob": [ - "./**/*.ts", - "./**/*.tsx", - "../typings/main.d.ts", - "!node_modules/**/*.ts", - "!node_modules/**/*.tsx" - ], - "files": [ - "./client/client.ts", - "./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/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/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 } } diff --git a/lib/typings/emissary/emissary.d.ts b/lib/typings/emissary/emissary.d.ts index cbc484a3d..9e806b349 100644 --- a/lib/typings/emissary/emissary.d.ts +++ b/lib/typings/emissary/emissary.d.ts @@ -3,8 +3,6 @@ // Definitions by: vvakame // Definitions: https://github.com/borisyankov/DefinitelyTyped -/// - declare module Emissary { interface IEmitterStatic extends Mixto.IMixinStatic { new ():IEmitter; 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/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/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/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 index a13240feb..e6cae6543 100644 --- a/lib/typings/tsd.d.ts +++ b/lib/typings/tsd.d.ts @@ -1,9 +1,4 @@ /// -/// -/// -/// -/// -/// /// /// /// diff --git a/lib/worker/parent.ts b/lib/worker/parent.ts index dbc20078f..ca015f841 100644 --- a/lib/worker/parent.ts +++ b/lib/worker/parent.ts @@ -1,9 +1,5 @@ import {debugSync} from "./debug"; -import childprocess = require('child_process'); -var exec = childprocess.exec; -var spawn = childprocess.spawn; - import * as path from "path" import * as tsconfig from "tsconfig" From 65f0e93ab7375aacfd788de579982b27c601032e Mon Sep 17 00:00:00 2001 From: Guntars Asmanis-Graham Date: Sat, 26 Nov 2016 18:27:07 -0500 Subject: [PATCH 06/70] Make linter use tsserver diagnostics, fix a one off error --- dist/linter.js | 34 +++++++++++++++++++------------ dist/main/atomts.js | 11 +++++----- lib/linter.ts | 43 +++++++++++++++++++++++++--------------- lib/main/atomts.ts | 16 ++++++++------- lib/main/utils/fsUtil.ts | 2 +- 5 files changed, 63 insertions(+), 43 deletions(-) diff --git a/dist/linter.js b/dist/linter.js index 6629797a4..f3b5f772b 100644 --- a/dist/linter.js +++ b/dist/linter.js @@ -8,24 +8,32 @@ exports.provider = { scope: 'file', lintOnFly: true, lint: function (textEditor) { - console.log("lint called"); 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 []; + parent.client.executeGetErr({ files: [filePath], delay: 50 }); + return new Promise(function (resolve, reject) { + var unsub = parent.client.on("semanticDiag", function (result) { + if (result.file === filePath) { + try { + unsub(); + var errors = result.diagnostics.map(function (diag) { + return { + type: "Error", + filePath: filePath, + text: diag.text, + range: new atom_1.Range([diag.start.line - 1, diag.start.offset - 1], [diag.end.line - 1, diag.end.offset - 1]) + }; + }); + resolve(errors); + } + catch (error) { + resolve([]); + } + } + }); }); } }; diff --git a/dist/main/atomts.js b/dist/main/atomts.js index 7c056ffbf..5052c8f32 100644 --- a/dist/main/atomts.js +++ b/dist/main/atomts.js @@ -65,11 +65,10 @@ function readyToActivate() { var editorView = atom_space_pen_views_1.$(atom.views.getView(editor)); tooltipManager.attach(editorView, editor); var unsubSyntax = parent.client.on("syntaxDiag", function (diag) { - console.log("syntax errors", diag); }); var unsubSemantic = parent.client.on("semanticDiag", function (diag) { - console.log("semantic errors", diag); if (diag.file === filePath) { + console.log("semantic errors", diag); mainPanelView_1.errorView.setErrors(filePath, diag.diagnostics.map(function (error) { var preview = editor.buffer.getTextInRange(new _atom.Range([error.start.line - 1, error.start.offset - 1], [error.end.line - 1, error.end.offset - 1])); return { @@ -115,11 +114,11 @@ function readyToActivate() { var buffer = editor.buffer; var fasterChangeObserver = editor.buffer.onDidChange(function (diff) { parent.client.executeChange({ - endLine: diff.oldRange.end.row, - endOffset: diff.oldRange.end.column, + endLine: diff.oldRange.end.row + 1, + endOffset: diff.oldRange.end.column + 1, file: editor.getPath(), - line: diff.oldRange.start.row, - offset: diff.oldRange.start.column, + line: diff.oldRange.start.row + 1, + offset: diff.oldRange.start.column + 1, insertString: diff.newText, }); }); diff --git a/lib/linter.ts b/lib/linter.ts index 05997222a..88652646f 100644 --- a/lib/linter.ts +++ b/lib/linter.ts @@ -25,8 +25,6 @@ export var provider = { lintOnFly: true, // # must be false for scope: 'project' lint: (textEditor: AtomCore.IEditor): Promise => { - console.log("lint called") - // We do not support files not on disk if (!textEditor.buffer.file || !textEditor.buffer.file.path @@ -34,21 +32,34 @@ export var provider = { var filePath = textEditor.buffer.file.path; - return parent.errorsForFile({ filePath: filePath }) - .then((resp) => { - var linterErrors: LinterMessage[] = resp.errors.map((err) => ({ + // Trigger an error check + parent.client.executeGetErr({files: [filePath], delay: 50}) + + return new Promise((resolve, reject) => { + + // Listen for a semanticDiag message for this specific file, unsub and resolve + const unsub = parent.client.on("semanticDiag", result => { + if (result.file === filePath) { + try { + unsub() + + const errors: LinterMessage[] = result.diagnostics.map(diag => { + return { 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 []; - }); + text: diag.text, + range: new Range( + [diag.start.line-1, diag.start.offset-1], + [diag.end.line-1, diag.end.offset-1]) + } + }) + + resolve(errors) + } catch (error) { + resolve([]) + } + } + }) + }) } } diff --git a/lib/main/atomts.ts b/lib/main/atomts.ts index 303affede..faa268081 100644 --- a/lib/main/atomts.ts +++ b/lib/main/atomts.ts @@ -140,13 +140,13 @@ function readyToActivate() { // Listen for error events for this file and display them const unsubSyntax = parent.client.on("syntaxDiag", diag => { - console.log("syntax errors", diag) + // console.log("syntax errors", diag) }) const unsubSemantic = parent.client.on("semanticDiag", diag => { - console.log("semantic errors", diag) - if (diag.file === filePath) { + console.log("semantic errors", diag) + errorView.setErrors(filePath, diag.diagnostics.map(error => { const preview = editor.buffer.getTextInRange( new _atom.Range( @@ -160,6 +160,8 @@ function readyToActivate() { message: ts.flattenDiagnosticMessageText(error.text, '\n'), preview } + + })) } }) @@ -258,11 +260,11 @@ function readyToActivate() { // stack(); parent.client.executeChange({ - endLine: diff.oldRange.end.row, - endOffset: diff.oldRange.end.column, + endLine: diff.oldRange.end.row+1, + endOffset: diff.oldRange.end.column+1, file: editor.getPath(), - line: diff.oldRange.start.row, - offset: diff.oldRange.start.column, + line: diff.oldRange.start.row+1, + offset: diff.oldRange.start.column+1, insertString: diff.newText, }) diff --git a/lib/main/utils/fsUtil.ts b/lib/main/utils/fsUtil.ts index 5550b9ef2..f5d1af65f 100644 --- a/lib/main/utils/fsUtil.ts +++ b/lib/main/utils/fsUtil.ts @@ -38,4 +38,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 +} From 758d28b02d72c2dd544682e24d3afe387cb46faf Mon Sep 17 00:00:00 2001 From: Guntars Asmanis-Graham Date: Sat, 26 Nov 2016 20:51:29 -0500 Subject: [PATCH 07/70] Show pending requests --- dist/client/client.js | 30 ++++++++++++++++++++--------- dist/linter.js | 2 +- dist/worker/parent.js | 10 +++++----- lib/client/client.ts | 44 +++++++++++++++++++++++++++++++------------ lib/linter.ts | 2 +- lib/worker/parent.ts | 13 +++++++------ 6 files changed, 67 insertions(+), 34 deletions(-) diff --git a/dist/client/client.js b/dist/client/client.js index 827d433db..ff580617d 100644 --- a/dist/client/client.js +++ b/dist/client/client.js @@ -28,17 +28,12 @@ var TypescriptServiceClient = (function () { else { callback.reject(new Error(res.message)); } + _this.emitPendingRequests(); } } else if (isEvent(res)) { console.log("received event", res); - var listeners = _this.listeners[res.event]; - if (listeners) { - for (var _i = 0, listeners_1 = listeners; _i < listeners_1.length; _i++) { - var listener = listeners_1[_i]; - listener(res.body); - } - } + _this.emit(res.event, res.body); } }; this.tsServerPath = tsServerPath; @@ -86,6 +81,22 @@ var TypescriptServiceClient = (function () { _this.listeners[name].splice(idx, 1); }; }; + TypescriptServiceClient.prototype.emit = function (name, data) { + var listeners = this.listeners[name]; + if (listeners) { + for (var _i = 0, listeners_1 = listeners; _i < listeners_1.length; _i++) { + var listener = listeners_1[_i]; + listener(data); + } + } + }; + TypescriptServiceClient.prototype.emitPendingRequests = function () { + var pending = []; + for (var callback in this.callbacks) { + pending.push(this.callbacks[callback].name); + } + this.emit("pendingRequestsChange", pending); + }; TypescriptServiceClient.prototype.sendRequest = function (cp, command, args, expectResponse) { var _this = this; var req = { @@ -97,8 +108,9 @@ var TypescriptServiceClient = (function () { var resultPromise = undefined; if (expectResponse) { resultPromise = new Promise(function (resolve, reject) { - _this.callbacks[req.seq] = { resolve: resolve, reject: reject, started: Date.now() }; + _this.callbacks[req.seq] = { name: command, resolve: resolve, reject: reject, started: Date.now() }; }); + this.emitPendingRequests(); } cp.stdin.write(JSON.stringify(req) + "\n"); return resultPromise; @@ -122,12 +134,12 @@ var TypescriptServiceClient = (function () { }; return TypescriptServiceClient; }()); +exports.TypescriptServiceClient = TypescriptServiceClient; TypescriptServiceClient.commandWithResponse = { completions: true, projectInfo: true, quickInfo: true }; -exports.TypescriptServiceClient = TypescriptServiceClient; function isEvent(res) { return res.type === "event"; } diff --git a/dist/linter.js b/dist/linter.js index f3b5f772b..11f47aeeb 100644 --- a/dist/linter.js +++ b/dist/linter.js @@ -13,7 +13,7 @@ exports.provider = { || !fs.existsSync(textEditor.buffer.file.path)) return Promise.resolve([]); var filePath = textEditor.buffer.file.path; - parent.client.executeGetErr({ files: [filePath], delay: 50 }); + parent.client.executeGetErr({ files: [filePath], delay: 100 }); return new Promise(function (resolve, reject) { var unsub = parent.client.on("semanticDiag", function (result) { if (result.file === filePath) { diff --git a/dist/worker/parent.js b/dist/worker/parent.js index 53aaa948c..a5e2cb4f3 100644 --- a/dist/worker/parent.js +++ b/dist/worker/parent.js @@ -6,11 +6,6 @@ var atomConfig = require("../main/atom/atomConfig"); var client_1 = require("../client/client"); 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; }; @@ -81,6 +76,11 @@ var queryParent = require("./queryParent"); parent.registerAllFunctionsExportedFromAsResponders(queryParent); var tsserverPath = client_1.findTSServer(__dirname); exports.client = new client_1.TypescriptServiceClient(tsserverPath); +exports.client.on("pendingRequestsChange", function (pending) { + if (!mainPanel.panelView) + return; + mainPanel.panelView.updatePendingRequests(pending); +}); function loadProjectConfig(sourcePath) { return exports.client.executeProjectInfo({ needFileNameList: false, file: sourcePath }).then(function (result) { return tsconfig.load(result.body.configFileName); diff --git a/lib/client/client.ts b/lib/client/client.ts index c6c844db4..4adaf6a81 100644 --- a/lib/client/client.ts +++ b/lib/client/client.ts @@ -11,6 +11,7 @@ export class TypescriptServiceClient { /** Map of callbacks that are waiting for responses */ callbacks: { [seq: number]: { + name: string reject(res) resolve(res) started: number @@ -21,8 +22,7 @@ export class TypescriptServiceClient { [event: string]: ((event: any) => any)[] } = {} - /** Path to the tsserver executable */ - readonly tsServerPath: string + private seq = 0 /** The tsserver child process */ server: ChildProcess @@ -30,7 +30,8 @@ export class TypescriptServiceClient { /** Promise that resolves when the server is ready to accept requests */ serverPromise: Promise - private seq = 0 + /** Path to the tsserver executable */ + readonly tsServerPath: string constructor(tsServerPath: string) { this.tsServerPath = tsServerPath @@ -75,9 +76,10 @@ export class TypescriptServiceClient { }) } - /** Adds an event listener for tsserver events. Returns an unsubscribe function */ - on(name: "syntaxDiag", listener: (result: protocol.DiagnosticEventBody) => any): Function + /** Adds an event listener for tsserver or other events. Returns an unsubscribe 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 { if (this.listeners[name] === undefined) { this.listeners[name] = [] @@ -91,6 +93,25 @@ export class TypescriptServiceClient { } } + private emit(name: string, data: any) { + const listeners = this.listeners[name] + if (listeners) { + for (const listener of listeners) { + listener(data) + } + } + } + + private emitPendingRequests() { + const pending = [] + + for (const callback in this.callbacks) { + pending.push(this.callbacks[callback].name) + } + + this.emit("pendingRequestsChange", pending) + } + private onMessage = (res: protocol.Response | protocol.Event) => { if (isResponse(res)) { const callback = this.callbacks[res.request_seq] @@ -102,15 +123,12 @@ export class TypescriptServiceClient { } else { callback.reject(new Error(res.message)) } + + this.emitPendingRequests() } } else if (isEvent(res)) { console.log("received event", res) - const listeners = this.listeners[res.event] - if (listeners) { - for (const listener of listeners) { - listener(res.body) - } - } + this.emit(res.event, res.body) } } @@ -128,8 +146,10 @@ export class TypescriptServiceClient { if (expectResponse) { resultPromise = new Promise((resolve, reject) => { - this.callbacks[req.seq] = {resolve, reject, started: Date.now()} + this.callbacks[req.seq] = {name: command, resolve, reject, started: Date.now()} }) + + this.emitPendingRequests() } cp.stdin.write(JSON.stringify(req) + "\n") diff --git a/lib/linter.ts b/lib/linter.ts index 88652646f..e71944a9b 100644 --- a/lib/linter.ts +++ b/lib/linter.ts @@ -33,7 +33,7 @@ export var provider = { var filePath = textEditor.buffer.file.path; // Trigger an error check - parent.client.executeGetErr({files: [filePath], delay: 50}) + parent.client.executeGetErr({files: [filePath], delay: 100}) return new Promise((resolve, reject) => { diff --git a/lib/worker/parent.ts b/lib/worker/parent.ts index ca015f841..0a85e6745 100644 --- a/lib/worker/parent.ts +++ b/lib/worker/parent.ts @@ -11,12 +11,6 @@ import {TypescriptServiceClient, findTSServer} from "../client/client" 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) { @@ -109,6 +103,13 @@ parent.registerAllFunctionsExportedFromAsResponders(queryParent); const tsserverPath = findTSServer(__dirname) export const client = new TypescriptServiceClient(tsserverPath) +client.on("pendingRequestsChange", pending => { + // We only start once the panel view is initialized + if (!mainPanel.panelView) return; + + mainPanel.panelView.updatePendingRequests(pending); +}) + export function loadProjectConfig(sourcePath: string): Promise { return client.executeProjectInfo({needFileNameList: false, file: sourcePath}).then(result => { return tsconfig.load(result.body.configFileName) From 2bd645551ff07b3d9594964e8fa8ae8112cb139d Mon Sep 17 00:00:00 2001 From: Guntars Asmanis-Graham Date: Sat, 26 Nov 2016 21:26:57 -0500 Subject: [PATCH 08/70] Convert all uses of quickinfo --- dist/client/client.js | 6 ++-- dist/main/atom/commands/commands.js | 49 +++++++++++++++-------------- dist/main/atom/tooltipManager.js | 25 +++++++-------- lib/client/client.ts | 4 +-- lib/main/atom/commands/commands.ts | 15 +++++---- lib/main/atom/tooltipManager.ts | 31 ++++++++---------- 6 files changed, 65 insertions(+), 65 deletions(-) diff --git a/dist/client/client.js b/dist/client/client.js index ff580617d..3057fbece 100644 --- a/dist/client/client.js +++ b/dist/client/client.js @@ -58,7 +58,7 @@ var TypescriptServiceClient = (function () { return this.execute("projectInfo", args); }; TypescriptServiceClient.prototype.executeQuickInfo = function (args) { - return this.execute("quickInfo", args); + return this.execute("quickinfo", args); }; TypescriptServiceClient.prototype.execute = function (command, args) { var _this = this; @@ -134,12 +134,12 @@ var TypescriptServiceClient = (function () { }; return TypescriptServiceClient; }()); -exports.TypescriptServiceClient = TypescriptServiceClient; TypescriptServiceClient.commandWithResponse = { completions: true, projectInfo: true, - quickInfo: true + quickinfo: true }; +exports.TypescriptServiceClient = TypescriptServiceClient; function isEvent(res) { return res.type === "event"; } diff --git a/dist/main/atom/commands/commands.js b/dist/main/atom/commands/commands.js index 0d56ae276..a38e50e2e 100644 --- a/dist/main/atom/commands/commands.js +++ b/dist/main/atom/commands/commands.js @@ -249,30 +249,33 @@ function registerCommands() { var editor = atom.workspace.getActiveTextEditor(); var editorView = atom.views.getView(editor); var cursor = editor.getLastCursor(); - var position = atomUtils.getEditorPositionForBufferPosition(editor, cursor.getBufferPosition()); + var position = 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); - } - }); + parent.client.executeQuickInfo({ + file: filePath, + line: position.row + 1, + offset: position.column + 1 + }).then(function (_a) { + var _b = _a.body, displayString = _b.displayString, documentation = _b.documentation; + var decoration = editor.decorateMarker(cursor.getMarker(), { + type: 'overlay', + item: typeOverlayView_1.create(displayString, documentation) + }); + 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); + }).catch(function () { }); }); atom.commands.add('atom-workspace', 'typescript:go-to-next', function (e) { gotoHistory.gotoNext(); diff --git a/dist/main/atom/tooltipManager.js b/dist/main/atom/tooltipManager.js index b98e948fc..3a180dd85 100644 --- a/dist/main/atom/tooltipManager.js +++ b/dist/main/atom/tooltipManager.js @@ -63,21 +63,20 @@ function attach(editorView, editor) { 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(); + parent.client.executeQuickInfo({ + file: filePath, + line: bufferPt.row + 1, + offset: bufferPt.column + 1 + }).then(function (_a) { + var _b = _a.body, displayString = _b.displayString, documentation = _b.documentation; + var message = "" + escape(displayString) + ""; + if (documentation) { + message = message + ("
" + escape(documentation).replace(/(?:\r\n|\r|\n)/g, '
') + "
"); } - 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); - } + if (exprTypeTooltip) { + exprTypeTooltip.updateText(message); } - }); + }, function () { }); } function deactivate() { subscriber.unsubscribe(); diff --git a/lib/client/client.ts b/lib/client/client.ts index 4adaf6a81..09a0b84fd 100644 --- a/lib/client/client.ts +++ b/lib/client/client.ts @@ -41,7 +41,7 @@ export class TypescriptServiceClient { static commandWithResponse = { completions: true, projectInfo: true, - quickInfo: true + quickinfo: true } executeChange(args: protocol.ChangeRequestArgs) { @@ -63,7 +63,7 @@ export class TypescriptServiceClient { return this.execute("projectInfo", args) } executeQuickInfo(args: protocol.FileLocationRequestArgs): Promise { - return this.execute("quickInfo", args) + return this.execute("quickinfo", args) } execute(command: string, args): Promise { diff --git a/lib/main/atom/commands/commands.ts b/lib/main/atom/commands/commands.ts index 56c1c5337..5ee4360ca 100644 --- a/lib/main/atom/commands/commands.ts +++ b/lib/main/atom/commands/commands.ts @@ -325,13 +325,17 @@ export function registerCommands() { var editor = atom.workspace.getActiveTextEditor(); var editorView = atom.views.getView(editor); var cursor = editor.getLastCursor() - var position = atomUtils.getEditorPositionForBufferPosition(editor, cursor.getBufferPosition()); + var position = cursor.getBufferPosition() var filePath = editor.getPath(); - parent.quickInfo({ filePath, position }).then((resp) => { - if (resp.valid) { + + parent.client.executeQuickInfo({ + file: filePath, + line: position.row+1, + offset: position.column+1 + }).then(({body: {displayString, documentation}}) => { var decoration = editor.decorateMarker(cursor.getMarker(), { type: 'overlay', - item: createTypeOverlay(resp.name, resp.comment) + item: createTypeOverlay(displayString, documentation) }); var onKeydown = (e) => { @@ -349,8 +353,7 @@ export function registerCommands() { var cursorListener = editor.onDidChangeCursorPosition(destroyTypeOverlay); editorView.addEventListener('blur', destroyTypeOverlay); editorView.addEventListener('keydown', onKeydown); - } - }); + }).catch(() => { /* ignore errors */ }) }); atom.commands.add('atom-workspace', 'typescript:go-to-next', (e) => { diff --git a/lib/main/atom/tooltipManager.ts b/lib/main/atom/tooltipManager.ts index 69101174a..9a7ce9415 100644 --- a/lib/main/atom/tooltipManager.ts +++ b/lib/main/atom/tooltipManager.ts @@ -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,27 +88,22 @@ 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(); + parent.client.executeQuickInfo({ + file: filePath, + line: bufferPt.row+1, + offset: bufferPt.column+1 + }).then(({body: {displayString, documentation}}) => { + var message = `${escape(displayString) }`; + if (documentation) { + message = message + `
${escape(documentation).replace(/(?:\r\n|\r|\n)/g, '
') }
`; } - 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); - } + // Sorry about this "if". It's in the code I copied so I guess its there for a reason + if (exprTypeTooltip) { + exprTypeTooltip.updateText(message); } - }); + }, () => { /* ignore the errors */ }) } - function deactivate() { subscriber.unsubscribe(); clearExprTypeTimeout(); From 093442d9c6b3a3cc733aa7a312cd43430ec9f148 Mon Sep 17 00:00:00 2001 From: Guntars Asmanis-Graham Date: Wed, 30 Nov 2016 11:10:31 -0500 Subject: [PATCH 09/70] Worky work on the work work --- dist/client/client.js | 49 +++++++------ dist/client/clientMap.js | 1 + dist/client/clientResolver.js | 66 ++++++++++++++++++ dist/client/findServer.js | 79 +++++++++++++++++++++ dist/client/findTSServer.js | 87 +++++++++++++++++++++++ dist/main/atom/autoCompleteProvider.js | 46 +++++------- dist/main/atomts.js | 5 +- dist/worker/parent.js | 6 +- lib/client/client.ts | 63 +++++++++-------- lib/client/clientResolver.ts | 97 ++++++++++++++++++++++++++ lib/client/findServer.ts | 95 +++++++++++++++++++++++++ lib/main/atom/autoCompleteProvider.ts | 85 +++++++++++----------- lib/main/atomts.ts | 5 +- lib/tsconfig.json | 1 + lib/worker/parent.ts | 9 ++- package.json | 2 +- 16 files changed, 557 insertions(+), 139 deletions(-) create mode 100644 dist/client/clientMap.js create mode 100644 dist/client/clientResolver.js create mode 100644 dist/client/findServer.js create mode 100644 dist/client/findTSServer.js create mode 100644 lib/client/clientResolver.ts create mode 100644 lib/client/findServer.ts diff --git a/dist/client/client.js b/dist/client/client.js index 3057fbece..30d2b0308 100644 --- a/dist/client/client.js +++ b/dist/client/client.js @@ -6,12 +6,9 @@ var __extends = (this && this.__extends) || function (d, b) { }; var child_process_1 = require("child_process"); var stream_1 = require("stream"); -var fs = require("fs"); -var path = require("path"); -var resolve = require("resolve"); var byline = require("byline"); var TypescriptServiceClient = (function () { - function TypescriptServiceClient(tsServerPath) { + function TypescriptServiceClient(tsServerPath, tsServerVersion) { var _this = this; this.callbacks = {}; this.listeners = {}; @@ -37,7 +34,7 @@ var TypescriptServiceClient = (function () { } }; this.tsServerPath = tsServerPath; - this.serverPromise = this.startServer(); + this.tsServerVersion = tsServerVersion; } TypescriptServiceClient.prototype.executeChange = function (args) { this.execute("change", args); @@ -117,42 +114,44 @@ var TypescriptServiceClient = (function () { }; TypescriptServiceClient.prototype.startServer = function () { var _this = this; - return new Promise(function (resolve, reject) { - console.log("starting", _this.tsServerPath); - var cp = child_process_1.spawn(_this.tsServerPath, []); - cp.once("error", function (err) { - console.log("tsserver starting failed with", err); - reject(err); + if (!this.serverPromise) { + this.serverPromise = new Promise(function (resolve, reject) { + console.log("starting", _this.tsServerPath); + var cp = child_process_1.spawn(_this.tsServerPath, []); + cp.once("error", function (err) { + console.log("tsserver starting failed with", err); + reject(err); + }); + cp.once("exit", function (code) { + console.log("tsserver failed to start with code", code); + reject({ code: code }); + }); + messageStream(cp.stdout).on("data", _this.onMessage); + _this.sendRequest(cp, "ping", null, true).then(function (res) { return resolve(cp); }, function (err) { return resolve(cp); }); }); - cp.once("exit", function (code) { - console.log("tsserver failed to start with code", code); - reject({ code: code }); + return this.serverPromise.catch(function (error) { + _this.serverPromise = null; + throw error; }); - messageStream(cp.stdout).on("data", _this.onMessage); - _this.sendRequest(cp, "ping", null, true).then(function (res) { return resolve(cp); }, function (err) { return resolve(cp); }); - }); + } + else { + throw new Error("Server already started: " + this.tsServerPath); + } }; return TypescriptServiceClient; }()); +exports.TypescriptServiceClient = TypescriptServiceClient; TypescriptServiceClient.commandWithResponse = { completions: true, projectInfo: true, quickinfo: true }; -exports.TypescriptServiceClient = TypescriptServiceClient; function isEvent(res) { return res.type === "event"; } function isResponse(res) { return res.type === "response"; } -function findTSServer(basedir) { - var tsPath = resolve.sync("typescript/package.json", { basedir: basedir }); - var tsServerPath = path.resolve(path.dirname(tsPath), "bin", "tsserver"); - fs.statSync(tsServerPath); - return tsServerPath; -} -exports.findTSServer = findTSServer; function messageStream(input) { return input.pipe(byline()).pipe(new MessageStream()); } diff --git a/dist/client/clientMap.js b/dist/client/clientMap.js new file mode 100644 index 000000000..3918c74e4 --- /dev/null +++ b/dist/client/clientMap.js @@ -0,0 +1 @@ +"use strict"; diff --git a/dist/client/clientResolver.js b/dist/client/clientResolver.js new file mode 100644 index 000000000..b60100ab3 --- /dev/null +++ b/dist/client/clientResolver.js @@ -0,0 +1,66 @@ +"use strict"; +var findServer_1 = require("./findServer"); +var client_1 = require("./client"); +var path = require("path"); +var nodeResolve = require("resolve"); +var defaultServerPath = require.resolve("typescript/bin/tsserver"); +var defaultServerVersion = require("typescript/package.json").version; +var defaultServer = new client_1.TypescriptServiceClient(defaultServerPath, defaultServerVersion); +var ClientResolver = (function () { + function ClientResolver() { + this.clients = []; + } + ClientResolver.prototype.get = function (filePath) { + var client = this.clients.find(function (client) { return filePath.startsWith(client.prefix); }); + if (client) { + return Promise.resolve(client.client); + } + return this.resolveFrom(filePath); + }; + ClientResolver.prototype.addClient = function (prefix, client) { + var existingClient = this.clients.find(function (client) { return client.prefix === prefix; }); + if (existingClient) { + return; + } + this.clients.push({ + prefix: prefix, + client: client + }); + if (!client.serverPromise) { + client.startServer(); + } + this.clients.sort(function (a, b) { return a.prefix.length - b.prefix.length; }); + }; + ClientResolver.prototype.resolveFrom = function (filePath) { + var _this = this; + var basedir = path.dirname(filePath); + return resolveLocalServer(basedir) + .then(function (tsServerPath) { return path.resolve(tsServerPath, "..", "..", "..", ".."); }) + .then(findServer_1.findTypescriptServers) + .then(function (servers) { + console.log("got some servers", servers); + for (var _i = 0, servers_1 = servers; _i < servers_1.length; _i++) { + var server = servers_1[_i]; + _this.addClient(server.prefix, new client_1.TypescriptServiceClient(server.binPath, server.version)); + } + return _this.get(filePath); + }).catch(function () { + _this.addClient(basedir, defaultServer); + return defaultServer; + }); + }; + return ClientResolver; +}()); +exports.ClientResolver = ClientResolver; +function resolveLocalServer(basedir) { + return new Promise(function (resolve, reject) { + nodeResolve("typescript/bin/tsserver", { basedir: basedir }, function (err, resolvedPath) { + if (err) { + reject(err); + } + else { + resolve(resolvedPath); + } + }); + }); +} diff --git a/dist/client/findServer.js b/dist/client/findServer.js new file mode 100644 index 000000000..fefc666dd --- /dev/null +++ b/dist/client/findServer.js @@ -0,0 +1,79 @@ +"use strict"; +var fs = require("fs"); +var path = require("path"); +function findTypescriptServers(root) { + var results = []; + if (!path.isAbsolute(root)) { + throw new Error("Argument should be an absolute path"); + } + return new Promise(function (resolve) { + walk(root, function () { + resolve(results); + }); + }); + function walk(dir, done) { + fs.readdir(dir, function (err, files) { + if (err || files.length === 0) + return done(); + var doneEntry = after(files.length, function () { + done(); + }); + for (var _i = 0, files_1 = files; _i < files_1.length; _i++) { + var entry = files_1[_i]; + if (entry === "node_modules") { + fs.stat(path.join(dir, entry, "typescript"), function (err) { + if (err) { + doneEntry(); + } + else { + getServerInfo(dir, function (err, info) { + if (info) + results.push(info); + doneEntry(); + }); + } + }); + } + else if (entry === ".git" || entry === "bower_components") { + doneEntry(); + } + else { + walk(path.join(dir, entry), doneEntry); + } + } + }); + } +} +exports.findTypescriptServers = findTypescriptServers; +function getServerInfo(prefix, callback) { + var tsDir = path.join(prefix, "node_modules", "typescript"); + fs.readFile(path.join(tsDir, "package.json"), "utf8", function (err, pkg) { + if (err) + return callback(err, null); + try { + var version_1 = JSON.parse(pkg).version; + var tsServerPath_1 = path.join(tsDir, "bin", "tsserver"); + fs.stat(tsServerPath_1, function (err, stat) { + if (err) + return callback(err, null); + callback(null, { + binPath: tsServerPath_1, + prefix: prefix, + version: version_1 + }); + }); + } + catch (error) { + callback(error, null); + } + }); +} +function after(count, callback) { + var called = 0; + return function () { + called++; + if (called >= count) { + callback.apply(this, arguments); + } + }; +} diff --git a/dist/client/findTSServer.js b/dist/client/findTSServer.js new file mode 100644 index 000000000..4c98f35f0 --- /dev/null +++ b/dist/client/findTSServer.js @@ -0,0 +1,87 @@ +"use strict"; +var fs = require("fs"); +var path = require("path"); +var resolve = require("resolve"); +function findTSServer(basedir) { + var tsPath = resolve.sync("typescript/package.json", { basedir: basedir }); + var tsServerPath = path.resolve(path.dirname(tsPath), "bin", "tsserver"); + fs.statSync(tsServerPath); + return tsServerPath; +} +exports.findTSServer = findTSServer; +function findTypescriptServers(root) { + var results = []; + if (!path.isAbsolute(root)) { + throw new Error("Argument should be an absolute path"); + } + return new Promise(function (resolve) { + walk(root, function () { + resolve(results); + }); + }); + function walk(dir, done) { + fs.readdir(dir, function (err, files) { + if (err || files.length === 0) + return done(); + var doneEntry = after(files.length, function () { + done(); + }); + for (var _i = 0, files_1 = files; _i < files_1.length; _i++) { + var entry = files_1[_i]; + if (entry === "node_modules") { + fs.stat(path.join(dir, entry, "typescript"), function (err) { + if (err) { + doneEntry(); + } + else { + getServerInfo(dir, function (err, info) { + if (info) + results.push(info); + doneEntry(); + }); + } + }); + } + else if (entry === ".git" || entry === "bower_components") { + doneEntry(); + } + else { + walk(path.join(dir, entry), doneEntry); + } + } + }); + } +} +exports.findTypescriptServers = findTypescriptServers; +function getServerInfo(prefix, callback) { + var tsDir = path.join(prefix, "node_modules", "typescript"); + fs.readFile(path.join(tsDir, "package.json"), "utf8", function (err, pkg) { + if (err) + return callback(err, null); + try { + var version_1 = JSON.parse(pkg).version; + var tsServerPath_1 = path.join(tsDir, "bin", "tsserver"); + fs.stat(tsServerPath_1, function (err, stat) { + if (err) + return callback(err, null); + callback(null, { + binPath: tsServerPath_1, + prefix: prefix, + version: version_1 + }); + }); + } + catch (error) { + callback(error, null); + } + }); +} +function after(count, callback) { + var called = 0; + return function () { + called++; + if (called >= count) { + callback.apply(this, arguments); + } + }; +} diff --git a/dist/main/atom/autoCompleteProvider.js b/dist/main/atom/autoCompleteProvider.js index a69fdb69c..c85fe3927 100644 --- a/dist/main/atom/autoCompleteProvider.js +++ b/dist/main/atom/autoCompleteProvider.js @@ -65,37 +65,27 @@ exports.provider = { return Promise.resolve([]); } } - var position = atomUtils.getEditorPositionForBufferPosition(options.editor, options.bufferPosition); - var promisedSuggestions = parent.getCompletionsAtPosition({ - filePath: filePath, - position: position, + var promisedSuggestions = parent.client.executeCompletions({ + file: filePath, prefix: options.prefix, - }) - .then(function (resp) { - var completionList = resp.completions; + line: options.bufferPosition.row + 1, + offset: options.bufferPosition.column + 1 + }).then(function (resp) { + console.log("prefix", options.prefix); + var completionList = resp.body; 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, - }; + var prefix = options.prefix; + if (c.name && c.name.startsWith('$')) { + prefix = "$" + prefix; } + return { + text: c.name, + replacementPrefix: prefix.trim(), + rightLabel: c.name, + leftLabel: c.kind, + type: atomUtils.kindToType(c.kind), + description: null, + }; }); return suggestions; }); diff --git a/dist/main/atomts.js b/dist/main/atomts.js index 5052c8f32..c95d4633f 100644 --- a/dist/main/atomts.js +++ b/dist/main/atomts.js @@ -86,7 +86,10 @@ function readyToActivate() { var isTst = ext === '.tst'; try { onlyOnceStuff(); - parent.client.executeOpen({ file: filePath }); + parent.client.executeOpen({ + file: filePath, + fileContent: editor.getText() + }); updatePanelConfig(filePath); var onDisk = false; if (fs.existsSync(filePath)) { diff --git a/dist/worker/parent.js b/dist/worker/parent.js index a5e2cb4f3..300ae76ec 100644 --- a/dist/worker/parent.js +++ b/dist/worker/parent.js @@ -1,6 +1,6 @@ "use strict"; var debug_1 = require("./debug"); -var tsconfig = require("tsconfig"); +var tsconfig = require("tsconfig/dist/tsconfig"); var workerLib = require("./lib/workerLib"); var atomConfig = require("../main/atom/atomConfig"); var client_1 = require("../client/client"); @@ -39,7 +39,6 @@ function catchCommonErrors(func) { } 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: [], @@ -74,8 +73,7 @@ exports.createProject = parent.sendToIpc(projectService.createProject); exports.toggleBreakpoint = parent.sendToIpc(projectService.toggleBreakpoint); var queryParent = require("./queryParent"); parent.registerAllFunctionsExportedFromAsResponders(queryParent); -var tsserverPath = client_1.findTSServer(__dirname); -exports.client = new client_1.TypescriptServiceClient(tsserverPath); +exports.client = new client_1.TypescriptServiceClient("haha", "Hehe"); exports.client.on("pendingRequestsChange", function (pending) { if (!mainPanel.panelView) return; diff --git a/lib/client/client.ts b/lib/client/client.ts index 09a0b84fd..5c6deaea3 100644 --- a/lib/client/client.ts +++ b/lib/client/client.ts @@ -1,9 +1,6 @@ import {ChildProcess, spawn} from "child_process" import {EventEmitter} from "events" import {Transform, Readable} from "stream" -import * as fs from "fs" -import * as path from "path" -import * as resolve from "resolve" import byline = require("byline") export class TypescriptServiceClient { @@ -30,12 +27,17 @@ export class TypescriptServiceClient { /** Promise that resolves when the server is ready to accept requests */ serverPromise: Promise + private serverDeferred: {resolve(), reject()} + /** Path to the tsserver executable */ readonly tsServerPath: string - constructor(tsServerPath: string) { + /** Version of the tsserver */ + readonly tsServerVersion: string + + constructor(tsServerPath: string, tsServerVersion: string) { this.tsServerPath = tsServerPath - this.serverPromise = this.startServer() + this.tsServerVersion = tsServerVersion } static commandWithResponse = { @@ -157,27 +159,37 @@ export class TypescriptServiceClient { return resultPromise } - private startServer(): Promise { - return new Promise((resolve, reject) => { - console.log("starting", this.tsServerPath) + startServer() { + if (!this.serverPromise) { + this.serverPromise = new Promise((resolve, reject) => { + console.log("starting", this.tsServerPath) - const cp = spawn(this.tsServerPath, []) + const cp = spawn(this.tsServerPath, []) - cp.once("error", err => { - console.log("tsserver starting failed with", err) - reject(err) - }) + cp.once("error", err => { + console.log("tsserver starting failed with", err) + reject(err) + }) - cp.once("exit", code => { - console.log("tsserver failed to start with code", code) - reject({code}) + cp.once("exit", code => { + console.log("tsserver failed to start with code", code) + reject({code}) + }) + + messageStream(cp.stdout).on("data", this.onMessage) + + // 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)) }) - messageStream(cp.stdout).on("data", this.onMessage) + return this.serverPromise.catch(error => { + this.serverPromise = null + throw error + }) - // 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}`) + } } } @@ -189,17 +201,6 @@ function isResponse(res: protocol.Response | protocol.Event): res is protocol.Re return res.type === "response" } -/** Given a start directory, try to resolve tsserver executable from node_modules */ -export function findTSServer(basedir: string): string { - const tsPath = resolve.sync("typescript/package.json", {basedir}) - const tsServerPath = path.resolve(path.dirname(tsPath), "bin", "tsserver") - - // This will throw if the file does not exist on the disk - fs.statSync(tsServerPath) - - return tsServerPath -} - function messageStream(input: Readable) { return input.pipe(byline()).pipe(new MessageStream()) } diff --git a/lib/client/clientResolver.ts b/lib/client/clientResolver.ts new file mode 100644 index 000000000..c6a454999 --- /dev/null +++ b/lib/client/clientResolver.ts @@ -0,0 +1,97 @@ +import {findTypescriptServers} from "./findServer" +import {TypescriptServiceClient} from "./client" +import * as fs from "fs" +import * as path from "path" +import * as nodeResolve from "resolve" + +const defaultServerPath = require.resolve("typescript/bin/tsserver") +const defaultServerVersion = require("typescript/package.json").version +const defaultServer = new TypescriptServiceClient(defaultServerPath, defaultServerVersion) + +/** + * 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 { + clients: { + prefix: string, + client: TypescriptServiceClient + }[] = [] + + get(filePath: string): Promise { + const client = this.clients.find(client => filePath.startsWith(client.prefix)) + + if (client) { + return Promise.resolve(client.client) + } + + // If we didn't find a client in the clients array, we need to resolve, start and add a new one + return this.resolveFrom(filePath) + } + + private addClient(prefix: string, client: TypescriptServiceClient) { + const existingClient = this.clients.find(client => client.prefix === prefix) + + if (existingClient) { + return + } + + this.clients.push({ + prefix, + client + }) + + if (!client.serverPromise) { + client.startServer() + } + + // Sort the clients in the descending order of the prefix length + this.clients.sort((a, b) => a.prefix.length - b.prefix.length) + } + + private resolveFrom(filePath: string): Promise { + const basedir = path.dirname(filePath) + + return resolveLocalServer(basedir) + .then(tsServerPath => path.resolve(tsServerPath, "..", "..", "..", "..")) + .then(findTypescriptServers) + .then(servers => { + console.log("got some servers", servers) + + for (const server of servers) { + this.addClient(server.prefix, new TypescriptServiceClient(server.binPath, server.version)) + } + + // + return this.get(filePath) + + }).catch(() => { + // TODO: Ensure there are no nested servers under the basedir too + this.addClient(basedir, defaultServer) + return defaultServer + }) + } +} + +function resolveLocalServer(basedir: string): Promise { + return new Promise((resolve, reject) => { + nodeResolve("typescript/bin/tsserver", {basedir}, (err, resolvedPath) => { + if (err) { + reject(err) + } else { + resolve(resolvedPath) + } + }) + }) +} + +// /** Given a start directory, try to resolve tsserver executable from node_modules */ +// export function findTSServer(basedir: string): string { +// const tsPath = resolve.sync("typescript/package.json", {basedir}) +// const tsServerPath = path.resolve(path.dirname(tsPath), "bin", "tsserver") +// +// // This will throw if the file does not exist on the disk +// fs.statSync(tsServerPath) +// +// return tsServerPath +// } diff --git a/lib/client/findServer.ts b/lib/client/findServer.ts new file mode 100644 index 000000000..a56a074f6 --- /dev/null +++ b/lib/client/findServer.ts @@ -0,0 +1,95 @@ +import * as fs from "fs" +import * as path from "path" + +export interface Server { + /** Path the the tsserver executable */ + binPath: string + + /* Path where the node_modules directory is that contains the typescript installation */ + prefix: string + + /* Version of Typescript */ + version: string +} + +/** Recursively search all directories rooted at the argument and find all typescript modules */ +export function findTypescriptServers(root: string): Promise { + const results: Server[] = [] + + if (!path.isAbsolute(root)) { + throw new Error("Argument should be an absolute path") + } + + return new Promise(resolve => { + walk(root, () => { + resolve(results) + }) + }) + + function walk(dir: string, done: Function) { + fs.readdir(dir, (err, files) => { + if (err || files.length === 0) return done() + + const doneEntry = after(files.length, () => { + done() + }) + + for (const entry of files) { + if (entry === "node_modules") { + fs.stat(path.join(dir, entry, "typescript"), err => { + if (err) { + doneEntry() + } else { + getServerInfo(dir, (err, info) => { + if (info) results.push(info) + doneEntry() + }) + } + }) + } else if (entry === ".git" || entry === "bower_components") { + doneEntry() + } else { + walk(path.join(dir, entry), doneEntry) + } + } + }) + } +} + +/** Get info about the tsserver at the prefix */ +function getServerInfo(prefix: string, callback: (err: Error, info: Server) => any) { + const tsDir = path.join(prefix, "node_modules", "typescript") + + fs.readFile(path.join(tsDir, "package.json"), "utf8", (err, pkg) => { + if (err) return callback(err, null) + + try { + const version = JSON.parse(pkg).version + const tsServerPath = path.join(tsDir, "bin", "tsserver") + + fs.stat(tsServerPath, (err, stat) => { + if (err) return callback(err, null) + + callback(null, { + binPath: tsServerPath, + prefix, + version + }) + }) + } catch (error) { + callback(error, null) + } + }) +} + +function after(count: number, callback: Function) { + let called = 0 + + return function() { + called++ + + if (called >= count) { + callback.apply(this, arguments) + } + } +} diff --git a/lib/main/atom/autoCompleteProvider.ts b/lib/main/atom/autoCompleteProvider.ts index 702224de5..149e96819 100644 --- a/lib/main/atom/autoCompleteProvider.ts +++ b/lib/main/atom/autoCompleteProvider.ts @@ -147,53 +147,52 @@ export var provider: autocompleteplus.Provider = { } } - 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', - }; + var promisedSuggestions = parent.client.executeCompletions({ + file: filePath, + prefix: options.prefix, + line: options.bufferPosition.row+1, + offset: options.bufferPosition.column+1 + }).then(resp => { + console.log("prefix", options.prefix) + + var completionList = resp.body; + var suggestions: autocompleteplus.Suggestion[] = completionList.map(c => { + + // 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; } - 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 { + text: c.name, + replacementPrefix: prefix.trim(), + rightLabel: c.name, + leftLabel: c.kind, + type: atomUtils.kindToType(c.kind), + description: null, + }; + // } }); + return suggestions; + }); + return promisedSuggestions; } }, diff --git a/lib/main/atomts.ts b/lib/main/atomts.ts index faa268081..a878981e2 100644 --- a/lib/main/atomts.ts +++ b/lib/main/atomts.ts @@ -173,7 +173,10 @@ function readyToActivate() { // Only once stuff onlyOnceStuff(); - parent.client.executeOpen({file: filePath}) + parent.client.executeOpen({ + file: filePath, + fileContent: editor.getText() + }) updatePanelConfig(filePath); diff --git a/lib/tsconfig.json b/lib/tsconfig.json index ee5b51c68..61b7546b7 100644 --- a/lib/tsconfig.json +++ b/lib/tsconfig.json @@ -3,6 +3,7 @@ "target": "es5", "module": "commonjs", "declaration": false, + "lib": ["es6", "dom"], "noImplicitAny": false, "removeComments": true, "noLib": false, diff --git a/lib/worker/parent.ts b/lib/worker/parent.ts index 0a85e6745..149272018 100644 --- a/lib/worker/parent.ts +++ b/lib/worker/parent.ts @@ -1,13 +1,13 @@ import {debugSync} from "./debug"; import * as path from "path" -import * as tsconfig from "tsconfig" +import * as tsconfig from "tsconfig/dist/tsconfig" import workerLib = require('./lib/workerLib'); import * as protocol from "typescript/lib/protocol"; import * as atomConfig from "../main/atom/atomConfig"; -import {TypescriptServiceClient, findTSServer} from "../client/client" +import {TypescriptServiceClient} from "../client/client" var parent = new workerLib.Parent(); import * as mainPanel from "../main/atom/views/mainPanelView"; @@ -61,7 +61,6 @@ function catchCommonErrors(func: workerLib.QRFunction { // We only start once the panel view is initialized diff --git a/package.json b/package.json index 12cbc0ba3..ef4e2a69f 100644 --- a/package.json +++ b/package.json @@ -75,7 +75,7 @@ "resolve": "1.1.7", "season": "^5.1.4", "tsconfig": "^2.2.0", - "typescript": "2.2.0-dev.20161118", + "typescript": "^2.2.0-dev.20161127", "xtend": "^4.0.0" }, "devDependencies": { From ad6d9324764170048657d00114ad6e416e239803 Mon Sep 17 00:00:00 2001 From: Guntars Asmanis-Graham Date: Wed, 30 Nov 2016 12:55:54 -0500 Subject: [PATCH 10/70] Update Typescript --- grammars/ts.cson | 499 ++++++++++++++++++++++++++++++++++----------- grammars/tsx.cson | 503 +++++++++++++++++++++++++++++++++++----------- package.json | 4 +- 3 files changed, 764 insertions(+), 242 deletions(-) diff --git a/grammars/ts.cson b/grammars/ts.cson index 1126d540e..fffe3c266 100644 --- a/grammars/ts.cson +++ b/grammars/ts.cson @@ -1,6 +1,6 @@ # This file is generated by "scripts/grammar.ts" -# Last generated: Fri, 18 Nov 2016 19:03:32 GMT +# Last generated: Wed, 30 Nov 2016 17:55:07 GMT name: "TypeScript" scopeName: "source.ts" @@ -126,7 +126,28 @@ repository: patterns: [ { name: "meta.var-single-variable.expr.ts" - begin: "(?x)([_$[:alpha:]][_$[:alnum:]]*)(?=\\s* (=\\s*( (async\\s+) | (function\\s*[(<]) | (function\\s+) | ([_$[:alpha:]][_$[:alnum:]]*\\s*=>) | ((<([^<>]|\\<[^<>]+\\>)+>\\s*)?\\(([^()]|\\([^()]*\\))*\\)(\\s*:\\s*(.)*)?\\s*=>)) ) | (:\\s*( (<) | ([(]\\s*( ([)]) | (\\.\\.\\.) | ([_$[:alnum:]]+\\s*( ([:,?=])| ([)]\\s*=>) )) ))) ))" + begin: ''' + (?x)([_$[:alpha:]][_$[:alnum:]]*)(?=\\s* + (=\\s*( + (async\\s+) | + (function\\s*[(<]) | + (function\\s+) | + ([_$[:alpha:]][_$[:alnum:]]*\\s*=>) | + ((<([^<>]|\\<[^<>]+\\>)+>\\s*)?\\(([^()]|\\([^()]*\\))*\\)(\\s*:\\s*(.)*)?\\s*=>)) + ) | + (:\\s*( + (<) | + ([(]\\s*( + ([)]) | + (\\.\\.\\.) | + ([_$[:alnum:]]+\\s*( + ([:,?=])| + ([)]\\s*=>) + )) + ))) + ) + ) + ''' beginCaptures: "1": name: "meta.definition.variable.ts entity.name.function.ts" @@ -204,7 +225,7 @@ repository: include: "#comment" } { - begin: "(?=(([_$[:alpha:]][_$[:alnum:]]*)|(\\'[^']*\\')|(\\\"[^\"]*\\\")|(\\[([^\\[\\]]|\\[[^\\[\\]]+\\])+\\]))\\s*(:))" + begin: "(?=(([_$[:alpha:]][_$[:alnum:]]*)|(\\'[^']*\\')|(\\\"[^\"]*\\\")|(\\[([^\\[\\]]|\\[[^\\[\\]]*\\])+\\]))\\s*(:))" end: "(?=,|\\})" patterns: [ { @@ -229,7 +250,7 @@ repository: } ] "object-binding-element-propertyName": - begin: "(?=(([_$[:alpha:]][_$[:alnum:]]*)|(\\'[^']*\\')|(\\\"[^\"]*\\\")|(\\[([^\\[\\]]|\\[[^\\[\\]]+\\])+\\]))\\s*(:))" + begin: "(?=(([_$[:alpha:]][_$[:alnum:]]*)|(\\'[^']*\\')|(\\\"[^\"]*\\\")|(\\[([^\\[\\]]|\\[[^\\[\\]]*\\])+\\]))\\s*(:))" end: "(:)" endCaptures: "0": @@ -307,17 +328,6 @@ repository: } ] "ternary-expression": - begin: "(?=\\?)" - end: "(?=$|[;,})\\]])" - patterns: [ - { - include: "#ternary-operator" - } - { - include: "#expression" - } - ] - "ternary-operator": begin: "(\\?)" beginCaptures: "0": @@ -571,7 +581,7 @@ repository: ] } { - begin: "(?=((\\'[^']*\\')|(\\\"[^\"]*\\\")|(\\[([^\\[\\]]|\\[[^\\[\\]]+\\])+\\])))" + begin: "(?=((\\'[^']*\\')|(\\\"[^\"]*\\\")|(\\[([^\\[\\]]|\\[[^\\[\\]]*\\])+\\])))" end: "(?=,|\\}|$)" patterns: [ { @@ -782,7 +792,10 @@ repository: } { comment: "(default|*|name) as alias" - match: "(?x) (?: \\b(default)\\b | (\\*) | ([_$[:alpha:]][_$[:alnum:]]*)) \\s+ (as) \\s+ (?: (\\b default \\b | \\*) | ([_$[:alpha:]][_$[:alnum:]]*))" + match: ''' + (?x) (?: \\b(default)\\b | (\\*) | ([_$[:alpha:]][_$[:alnum:]]*)) \\s+ + (as) \\s+ (?: (\\b default \\b | \\*) | ([_$[:alpha:]][_$[:alnum:]]*)) + ''' captures: "1": name: "keyword.control.default.ts" @@ -992,7 +1005,7 @@ repository: ] "field-declaration": name: "meta.field.declaration.ts" - begin: "(?) | ((<([^<>]|\\<[^<>]+\\>)+>\\s*)?\\(([^()]|\\([^()]*\\))*\\)(\\s*:\\s*(.)*)?\\s*=>)) ) | (:\\s*( (<) | ([(]\\s*( ([)]) | (\\.\\.\\.) | ([_$[:alnum:]]+\\s*( ([:,?=])| ([)]\\s*=>) )) ))) ))" + match: ''' + (?x)([_$[:alpha:]][_$[:alnum:]]*)(?=(\\?\\s*)?\\s* + (=\\s*( + (async\\s+) | + (function\\s*[(<]) | + (function\\s+) | + ([_$[:alpha:]][_$[:alnum:]]*\\s*=>) | + ((<([^<>]|\\<[^<>]+\\>)+>\\s*)?\\(([^()]|\\([^()]*\\))*\\)(\\s*:\\s*(.)*)?\\s*=>)) + ) | + (:\\s*( + (<) | + ([(]\\s*( + ([)]) | + (\\.\\.\\.) | + ([_$[:alnum:]]+\\s*( + ([:,?=])| + ([)]\\s*=>) + )) + ))) + ) + ) + ''' } { name: "meta.definition.property.ts variable.object.property.ts" @@ -1034,7 +1068,7 @@ repository: ] "method-declaration": name: "meta.method.declaration.ts" - begin: "(?) | ((<([^<>]|\\<[^<>]+\\>)+>\\s*)?\\(([^()]|\\([^()]*\\))*\\)(\\s*:\\s*(.)*)?\\s*=>)) ) | (:\\s*( (<) | ([(]\\s*( ([)]) | (\\.\\.\\.) | ([_$[:alnum:]]+\\s*( ([:,?=])| ([)]\\s*=>) )) ))) ))" + match: "\\s*\\b(public|protected|private|readonly)(?=\\s+(public|protected|private|readonly)\\s+)" captures: "1": name: "storage.modifier.ts" - "2": + } + { + match: ''' + (?x)(?:\\s*\\b(public|private|protected|readonly)\\s+)?(\\.\\.\\.)?\\s*(?) | + ((<([^<>]|\\<[^<>]+\\>)+>\\s*)?\\(([^()]|\\([^()]*\\))*\\)(\\s*:\\s*(.)*)?\\s*=>)) + ) | + (:\\s*( + (<) | + ([(]\\s*( + ([)]) | + (\\.\\.\\.) | + ([_$[:alnum:]]+\\s*( + ([:,?=])| + ([)]\\s*=>) + )) + ))) + ) + ) + ''' + captures: + "1": name: "storage.modifier.ts" - "3": + "2": name: "keyword.operator.rest.ts" - "4": + "3": name: "entity.name.function.ts" - "5": + "4": name: "keyword.operator.optional.ts" } { - match: "(?:\\s*\\b(readonly)\\s+)?(?:\\s*\\b(public|private|protected)\\s+)?(\\.\\.\\.)?\\s*(?) )) ) ) )" + begin: ''' + (?x)( + (?= + [(]\\s*( + ([)]) | + (\\.\\.\\.) | + ([_$[:alnum:]]+\\s*( + ([:,?=])| + ([)]\\s*=>) + )) + ) + ) + ) + ''' end: "(?<=\\))" patterns: [ { @@ -1767,7 +1886,7 @@ repository: ] "switch-block": name: "switch-block.expr.ts" - begin: "{" + begin: "\\{" beginCaptures: "0": name: "punctuation.definition.block.ts" @@ -1798,7 +1917,7 @@ repository: "switch-statement": name: "switch-statement.expr.ts" begin: "(?)| ((<([^<>]|\\<[^<>]+\\>)+>\\s*)?\\(([^()]|\\([^()]*\\))*\\)(\\s*:\\s*(.)*)?\\s*=>)))" + match: ''' + (?x)(?:(\\.)\\s*)?([_$[:alpha:]][_$[:alnum:]]*)(?=\\s*=\\s*( + (async\\s+)|(function\\s*[(<])|(function\\s+)| + ([_$[:alpha:]][_$[:alnum:]]*\\s*=>)| + ((<([^<>]|\\<[^<>]+\\>)+>\\s*)?\\(([^()]|\\([^()]*\\))*\\)(\\s*:\\s*(.)*)?\\s*=>))) + ''' captures: "1": name: "punctuation.accessor.ts" @@ -2251,7 +2383,7 @@ repository: beginCaptures: "1": name: "meta.brace.angle.ts" - end: ">" + end: "\\>" endCaptures: "0": name: "meta.brace.angle.ts" @@ -2284,16 +2416,16 @@ repository: include: "#comment" } { - include: "#method-declaration" + include: "#object-literal-method-declaration" } { name: "meta.object.member.ts" - begin: "(?=(?:(?:\\'[^']*\\')|(?:\\\"[^\"]*\\\")|(?:\\[([^\\[\\]]|\\[[^\\[\\]]+\\])+\\]))\\s*:)" + begin: "(?=(?:(?:\\'[^']*\\')|(?:\\\"[^\"]*\\\")|(?:\\[([^\\[\\]]|\\[[^\\[\\]]*\\])+\\]))\\s*:)" end: "(?=,|\\})" patterns: [ { name: "meta.object-literal.key.ts" - begin: "(?=(?:(?:\\'[^']*\\')|(?:\\\"[^\"]*\\\")|(?:\\[([^\\[\\]]|\\[[^\\[\\]]+\\])+\\]))\\s*:)" + begin: "(?=(?:(?:\\'[^']*\\')|(?:\\\"[^\"]*\\\")|(?:\\[([^\\[\\]]|\\[[^\\[\\]]*\\])+\\]))\\s*:)" end: ":" endCaptures: "0": @@ -2314,7 +2446,12 @@ repository: } { name: "meta.object.member.ts" - begin: "(?x)(?:([_$[:alpha:]][_$[:alnum:]]*)\\s*(:)(?=\\s*( (async\\s+)|(function\\s*[(<])|(function\\s+)| ([_$[:alpha:]][_$[:alnum:]]*\\s*=>)| ((<([^<>]|\\<[^<>]+\\>)+>\\s*)?\\(([^()]|\\([^()]*\\))*\\)(\\s*:\\s*(.)*)?\\s*=>))))" + begin: ''' + (?x)(?:([_$[:alpha:]][_$[:alnum:]]*)\\s*(:)(?=\\s*( + (async\\s+)|(function\\s*[(<])|(function\\s+)| + ([_$[:alpha:]][_$[:alnum:]]*\\s*=>)| + ((<([^<>]|\\<[^<>]+\\>)+>\\s*)?\\(([^()]|\\([^()]*\\))*\\)(\\s*:\\s*(.)*)?\\s*=>)))) + ''' beginCaptures: "0": name: "meta.object-literal.key.ts" @@ -3019,78 +3156,171 @@ repository: patterns: [ { name: "storage.type.class.jsdoc" - match: "(? # {Array} or {Object} type application (optional .) - ) + [a-zA-Z_$][\\w$]* + (?: + \\s*,\\s* + [a-zA-Z_$][\\w$]* + )* + )? + \\s* + \\) + (?: # {function(): string} function return type + \\s*:\\s* + [a-zA-Z_$][\\w$]* + )? + )? + | (?: - [\\.|~] # {Foo.bar} namespaced, {string|number} multiple, {Foo~bar} class-specific callback + \\( # Opening bracket of multiple types with parenthesis {(string|number)} + [a-zA-Z_$]+ + (?: + (?: + [\\w$]* + (?:\\[\\])? # {(string[]|number)} type application, an array of strings or a number + ) | + \\.?<[\\w$]+(?:,\\s+[\\w$]+)*> # {Array} or {Object} type application (optional .) + ) + (?: + [\\.|~] # {Foo.bar} namespaced, {string|number} multiple, {Foo~bar} class-specific callback + [a-zA-Z_$]+ + (?: + (?: + [\\w$]* + (?:\\[\\])? # {(string|number[])} type application, a string or an array of numbers + ) | + \\.?<[\\w$]+(?:,\\s+[\\w$]+)*> # {Array} or {Object} type application (optional .) + ) + )* + \\) | [a-zA-Z_$]+ (?: (?: [\\w$]* - (?:\\[\\])? # {(string|number[])} type application, a string or an array of numbers + (?:\\[\\])? # {(string|number[])} type application, a string or an array of numbers ) | - \\.?<[\\w$]+(?:,\\s+[\\w$]+)*> # {Array} or {Object} type application (optional .) + \\.?<[\\w$]+(?:,\\s+[\\w$]+)*> # {Array} or {Object} type application (optional .) ) - )* - \\) | - [a-zA-Z_$]+ - (?: - (?: - [\\w$]* - (?:\\[\\])? # {string[]|number} type application, an array of strings or a number - ) | - \\.?<[\\w$]+(?:,\\s+[\\w$]+)*> # {Array} or {Object} type application (optional .) - ) - (?: - [\\.|~] # {Foo.bar} namespaced, {string|number} multiple, {Foo~bar} class-specific callback - [a-zA-Z_$]+ - (?: - [\\w$]* | - \\.?<[\\w$]+(?:,\\s+[\\w$]+)*> # {Array} or {Object} type application (optional .) + (?: + [\\.|~] # {Foo.bar} namespaced, {string|number} multiple, {Foo~bar} class-specific callback + [a-zA-Z_$]+ + (?: + [\\w$]* | + \\.?<[\\w$]+(?:,\\s+[\\w$]+)*> # {Array} or {Object} type application (optional .) + ) + )* ) - )* + ) + # Check for suffix + (?:\\[\\])? # {string[]} type application, an array of strings + =? # {string=} optional parameter ) - # Check for suffix - (?:\\[\\])? # {string[]} type application, an array of strings - =? # {string=} optional parameter )}) + \\s+ + ( \\[ # [foo] optional parameter \\s* (?: [a-zA-Z_$][\\w$]* (?: - (?:\\[\\])? # Foo[].bar properties within an array + (?:\\[\\])? # Foo[].bar properties within an array \\. # Foo.Bar namespaced parameter [a-zA-Z_$][\\w$]* )* (?: \\s* - = # [foo=bar] Default parameter value + = # [foo=bar] Default parameter value \\s* [\\w$\\s]* )? @@ -3100,14 +3330,17 @@ repository: (?: [a-zA-Z_$][\\w$]* (?: - (?:\\[\\])? # Foo[].bar properties within an array + (?:\\[\\])? # Foo[].bar properties within an array \\. # Foo.Bar namespaced parameter [a-zA-Z_$][\\w$]* )* )? ) + \\s+ - (?:-\\s+)? # optional hyphen before the description + + (?:-\\s+)? # optional hyphen before the description + ((?:(?!\\*\\/).)*) # The type description ''' captures: @@ -3123,53 +3356,81 @@ repository: { match: ''' (?x) + ({(?: \\* | # {*} any type \\? | # {?} unknown type - (?: # Check for a prefix - \\? | # {?string} nullable type - ! | # {!string} non-nullable type - \\.{3} # {...string} variable number of parameters - )? - (?: - \\( # Opening bracket of multiple types with parenthesis {(string|number)} - [a-zA-Z_$]+ + (?: # Check for a prefix + \\? | # {?string} nullable type + ! | # {!string} non-nullable type + \\.{3} # {...string} variable number of parameters + )? + + (?: (?: - [\\w$]* | - \\.?<[\\w$]+(?:,\\s+[\\w$]+)*> # {Array} or {Object} type application (optional .) - ) + function # {function(string, number)} function type + \\s* + \\( + \\s* + (?: + [a-zA-Z_$][\\w$]* + (?: + \\s*,\\s* + [a-zA-Z_$][\\w$]* + )* + )? + \\s* + \\) + (?: # {function(): string} function return type + \\s*:\\s* + [a-zA-Z_$][\\w$]* + )? + )? + | (?: - [\\.|~] # {Foo.bar} namespaced, {string|number} multiple, {Foo~bar} class-specific callback + \\( # Opening bracket of multiple types with parenthesis {(string|number)} + [a-zA-Z_$]+ + (?: + [\\w$]* | + \\.?<[\\w$]+(?:,\\s+[\\w$]+)*> # {Array} or {Object} type application (optional .) + ) + (?: + [\\.|~] # {Foo.bar} namespaced, {string|number} multiple, {Foo~bar} class-specific callback + [a-zA-Z_$]+ + (?: + [\\w$]* | + \\.?<[\\w$]+(?:,\\s+[\\w$]+)*> # {Array} or {Object} type application (optional .) + ) + )* + \\) | [a-zA-Z_$]+ (?: [\\w$]* | - \\.?<[\\w$]+(?:,\\s+[\\w$]+)*> # {Array} or {Object} type application (optional .) + \\.?<[\\w$]+(?:,\\s+[\\w$]+)*> # {Array} or {Object} type application (optional .) ) - )* - \\) | - [a-zA-Z_$]+ - (?: - [\\w$]* | - \\.?<[\\w$]+(?:,\\s+[\\w$]+)*> # {Array} or {Object} type application (optional .) - ) - (?: - [\\.|~] # {Foo.bar} namespaced, {string|number} multiple, {Foo~bar} class-specific callback - [a-zA-Z_$]+ - (?: - [\\w$]* | - \\.?<[\\w$]+(?:,\\s+[\\w$]+)*> # {Array} or {Object} type application (optional .) + (?: + [\\.|~] # {Foo.bar} namespaced, {string|number} multiple, {Foo~bar} class-specific callback + [a-zA-Z_$]+ + (?: + [\\w$]* | + \\.?<[\\w$]+(?:,\\s+[\\w$]+)*> # {Array} or {Object} type application (optional .) + ) + )* ) - )* + ) + # Check for suffix + (?:\\[\\])? # {string[]} type application, an array of strings + =? # {string=} optional parameter ) - # Check for suffix - (?:\\[\\])? # {string[]} type application, an array of strings - =? # {string=} optional parameter )}) + \\s+ + (?:-\\s+)? # optional hyphen before the description - ((?:(?!\\*\\/).)*) # The type description + + ((?:(?!\\*\\/).)*) # The type description ''' captures: "0": diff --git a/grammars/tsx.cson b/grammars/tsx.cson index 5872c8624..92f3245bb 100644 --- a/grammars/tsx.cson +++ b/grammars/tsx.cson @@ -1,6 +1,6 @@ # This file is generated by "scripts/grammar.ts" -# Last generated: Fri, 18 Nov 2016 19:03:32 GMT +# Last generated: Wed, 30 Nov 2016 17:55:07 GMT name: "TypeScriptReact" scopeName: "source.tsx" @@ -126,7 +126,28 @@ repository: patterns: [ { name: "meta.var-single-variable.expr.tsx" - begin: "(?x)([_$[:alpha:]][_$[:alnum:]]*)(?=\\s* (=\\s*( (async\\s+) | (function\\s*[(<]) | (function\\s+) | ([_$[:alpha:]][_$[:alnum:]]*\\s*=>) | ((<([^<>]|\\<[^<>]+\\>)+>\\s*)?\\(([^()]|\\([^()]*\\))*\\)(\\s*:\\s*(.)*)?\\s*=>)) ) | (:\\s*( (<) | ([(]\\s*( ([)]) | (\\.\\.\\.) | ([_$[:alnum:]]+\\s*( ([:,?=])| ([)]\\s*=>) )) ))) ))" + begin: ''' + (?x)([_$[:alpha:]][_$[:alnum:]]*)(?=\\s* + (=\\s*( + (async\\s+) | + (function\\s*[(<]) | + (function\\s+) | + ([_$[:alpha:]][_$[:alnum:]]*\\s*=>) | + ((<([^<>]|\\<[^<>]+\\>)+>\\s*)?\\(([^()]|\\([^()]*\\))*\\)(\\s*:\\s*(.)*)?\\s*=>)) + ) | + (:\\s*( + (<) | + ([(]\\s*( + ([)]) | + (\\.\\.\\.) | + ([_$[:alnum:]]+\\s*( + ([:,?=])| + ([)]\\s*=>) + )) + ))) + ) + ) + ''' beginCaptures: "1": name: "meta.definition.variable.tsx entity.name.function.tsx" @@ -204,7 +225,7 @@ repository: include: "#comment" } { - begin: "(?=(([_$[:alpha:]][_$[:alnum:]]*)|(\\'[^']*\\')|(\\\"[^\"]*\\\")|(\\[([^\\[\\]]|\\[[^\\[\\]]+\\])+\\]))\\s*(:))" + begin: "(?=(([_$[:alpha:]][_$[:alnum:]]*)|(\\'[^']*\\')|(\\\"[^\"]*\\\")|(\\[([^\\[\\]]|\\[[^\\[\\]]*\\])+\\]))\\s*(:))" end: "(?=,|\\})" patterns: [ { @@ -229,7 +250,7 @@ repository: } ] "object-binding-element-propertyName": - begin: "(?=(([_$[:alpha:]][_$[:alnum:]]*)|(\\'[^']*\\')|(\\\"[^\"]*\\\")|(\\[([^\\[\\]]|\\[[^\\[\\]]+\\])+\\]))\\s*(:))" + begin: "(?=(([_$[:alpha:]][_$[:alnum:]]*)|(\\'[^']*\\')|(\\\"[^\"]*\\\")|(\\[([^\\[\\]]|\\[[^\\[\\]]*\\])+\\]))\\s*(:))" end: "(:)" endCaptures: "0": @@ -307,17 +328,6 @@ repository: } ] "ternary-expression": - begin: "(?=\\?)" - end: "(?=$|[;,})\\]])" - patterns: [ - { - include: "#ternary-operator" - } - { - include: "#expression" - } - ] - "ternary-operator": begin: "(\\?)" beginCaptures: "0": @@ -574,7 +584,7 @@ repository: ] } { - begin: "(?=((\\'[^']*\\')|(\\\"[^\"]*\\\")|(\\[([^\\[\\]]|\\[[^\\[\\]]+\\])+\\])))" + begin: "(?=((\\'[^']*\\')|(\\\"[^\"]*\\\")|(\\[([^\\[\\]]|\\[[^\\[\\]]*\\])+\\])))" end: "(?=,|\\}|$)" patterns: [ { @@ -785,7 +795,10 @@ repository: } { comment: "(default|*|name) as alias" - match: "(?x) (?: \\b(default)\\b | (\\*) | ([_$[:alpha:]][_$[:alnum:]]*)) \\s+ (as) \\s+ (?: (\\b default \\b | \\*) | ([_$[:alpha:]][_$[:alnum:]]*))" + match: ''' + (?x) (?: \\b(default)\\b | (\\*) | ([_$[:alpha:]][_$[:alnum:]]*)) \\s+ + (as) \\s+ (?: (\\b default \\b | \\*) | ([_$[:alpha:]][_$[:alnum:]]*)) + ''' captures: "1": name: "keyword.control.default.tsx" @@ -995,7 +1008,7 @@ repository: ] "field-declaration": name: "meta.field.declaration.tsx" - begin: "(?) | ((<([^<>]|\\<[^<>]+\\>)+>\\s*)?\\(([^()]|\\([^()]*\\))*\\)(\\s*:\\s*(.)*)?\\s*=>)) ) | (:\\s*( (<) | ([(]\\s*( ([)]) | (\\.\\.\\.) | ([_$[:alnum:]]+\\s*( ([:,?=])| ([)]\\s*=>) )) ))) ))" + match: ''' + (?x)([_$[:alpha:]][_$[:alnum:]]*)(?=(\\?\\s*)?\\s* + (=\\s*( + (async\\s+) | + (function\\s*[(<]) | + (function\\s+) | + ([_$[:alpha:]][_$[:alnum:]]*\\s*=>) | + ((<([^<>]|\\<[^<>]+\\>)+>\\s*)?\\(([^()]|\\([^()]*\\))*\\)(\\s*:\\s*(.)*)?\\s*=>)) + ) | + (:\\s*( + (<) | + ([(]\\s*( + ([)]) | + (\\.\\.\\.) | + ([_$[:alnum:]]+\\s*( + ([:,?=])| + ([)]\\s*=>) + )) + ))) + ) + ) + ''' } { name: "meta.definition.property.tsx variable.object.property.tsx" @@ -1037,7 +1071,7 @@ repository: ] "method-declaration": name: "meta.method.declaration.tsx" - begin: "(?) | ((<([^<>]|\\<[^<>]+\\>)+>\\s*)?\\(([^()]|\\([^()]*\\))*\\)(\\s*:\\s*(.)*)?\\s*=>)) ) | (:\\s*( (<) | ([(]\\s*( ([)]) | (\\.\\.\\.) | ([_$[:alnum:]]+\\s*( ([:,?=])| ([)]\\s*=>) )) ))) ))" + match: "\\s*\\b(public|protected|private|readonly)(?=\\s+(public|protected|private|readonly)\\s+)" captures: "1": name: "storage.modifier.tsx" - "2": + } + { + match: ''' + (?x)(?:\\s*\\b(public|private|protected|readonly)\\s+)?(\\.\\.\\.)?\\s*(?) | + ((<([^<>]|\\<[^<>]+\\>)+>\\s*)?\\(([^()]|\\([^()]*\\))*\\)(\\s*:\\s*(.)*)?\\s*=>)) + ) | + (:\\s*( + (<) | + ([(]\\s*( + ([)]) | + (\\.\\.\\.) | + ([_$[:alnum:]]+\\s*( + ([:,?=])| + ([)]\\s*=>) + )) + ))) + ) + ) + ''' + captures: + "1": name: "storage.modifier.tsx" - "3": + "2": name: "keyword.operator.rest.tsx" - "4": + "3": name: "entity.name.function.tsx" - "5": + "4": name: "keyword.operator.optional.tsx" } { - match: "(?:\\s*\\b(readonly)\\s+)?(?:\\s*\\b(public|private|protected)\\s+)?(\\.\\.\\.)?\\s*(?) )) ) ) )" + begin: ''' + (?x)( + (?= + [(]\\s*( + ([)]) | + (\\.\\.\\.) | + ([_$[:alnum:]]+\\s*( + ([:,?=])| + ([)]\\s*=>) + )) + ) + ) + ) + ''' end: "(?<=\\))" patterns: [ { @@ -1770,7 +1889,7 @@ repository: ] "switch-block": name: "switch-block.expr.tsx" - begin: "{" + begin: "\\{" beginCaptures: "0": name: "punctuation.definition.block.tsx" @@ -1801,7 +1920,7 @@ repository: "switch-statement": name: "switch-statement.expr.tsx" begin: "(?)| ((<([^<>]|\\<[^<>]+\\>)+>\\s*)?\\(([^()]|\\([^()]*\\))*\\)(\\s*:\\s*(.)*)?\\s*=>)))" + match: ''' + (?x)(?:(\\.)\\s*)?([_$[:alpha:]][_$[:alnum:]]*)(?=\\s*=\\s*( + (async\\s+)|(function\\s*[(<])|(function\\s+)| + ([_$[:alpha:]][_$[:alnum:]]*\\s*=>)| + ((<([^<>]|\\<[^<>]+\\>)+>\\s*)?\\(([^()]|\\([^()]*\\))*\\)(\\s*:\\s*(.)*)?\\s*=>))) + ''' captures: "1": name: "punctuation.accessor.tsx" @@ -2278,16 +2410,16 @@ repository: include: "#comment" } { - include: "#method-declaration" + include: "#object-literal-method-declaration" } { name: "meta.object.member.tsx" - begin: "(?=(?:(?:\\'[^']*\\')|(?:\\\"[^\"]*\\\")|(?:\\[([^\\[\\]]|\\[[^\\[\\]]+\\])+\\]))\\s*:)" + begin: "(?=(?:(?:\\'[^']*\\')|(?:\\\"[^\"]*\\\")|(?:\\[([^\\[\\]]|\\[[^\\[\\]]*\\])+\\]))\\s*:)" end: "(?=,|\\})" patterns: [ { name: "meta.object-literal.key.tsx" - begin: "(?=(?:(?:\\'[^']*\\')|(?:\\\"[^\"]*\\\")|(?:\\[([^\\[\\]]|\\[[^\\[\\]]+\\])+\\]))\\s*:)" + begin: "(?=(?:(?:\\'[^']*\\')|(?:\\\"[^\"]*\\\")|(?:\\[([^\\[\\]]|\\[[^\\[\\]]*\\])+\\]))\\s*:)" end: ":" endCaptures: "0": @@ -2308,7 +2440,12 @@ repository: } { name: "meta.object.member.tsx" - begin: "(?x)(?:([_$[:alpha:]][_$[:alnum:]]*)\\s*(:)(?=\\s*( (async\\s+)|(function\\s*[(<])|(function\\s+)| ([_$[:alpha:]][_$[:alnum:]]*\\s*=>)| ((<([^<>]|\\<[^<>]+\\>)+>\\s*)?\\(([^()]|\\([^()]*\\))*\\)(\\s*:\\s*(.)*)?\\s*=>))))" + begin: ''' + (?x)(?:([_$[:alpha:]][_$[:alnum:]]*)\\s*(:)(?=\\s*( + (async\\s+)|(function\\s*[(<])|(function\\s+)| + ([_$[:alpha:]][_$[:alnum:]]*\\s*=>)| + ((<([^<>]|\\<[^<>]+\\>)+>\\s*)?\\(([^()]|\\([^()]*\\))*\\)(\\s*:\\s*(.)*)?\\s*=>)))) + ''' beginCaptures: "0": name: "meta.object-literal.key.tsx" @@ -3013,78 +3150,171 @@ repository: patterns: [ { name: "storage.type.class.jsdoc" - match: "(? # {Array} or {Object} type application (optional .) - ) + [a-zA-Z_$][\\w$]* + (?: + \\s*,\\s* + [a-zA-Z_$][\\w$]* + )* + )? + \\s* + \\) + (?: # {function(): string} function return type + \\s*:\\s* + [a-zA-Z_$][\\w$]* + )? + )? + | (?: - [\\.|~] # {Foo.bar} namespaced, {string|number} multiple, {Foo~bar} class-specific callback + \\( # Opening bracket of multiple types with parenthesis {(string|number)} + [a-zA-Z_$]+ + (?: + (?: + [\\w$]* + (?:\\[\\])? # {(string[]|number)} type application, an array of strings or a number + ) | + \\.?<[\\w$]+(?:,\\s+[\\w$]+)*> # {Array} or {Object} type application (optional .) + ) + (?: + [\\.|~] # {Foo.bar} namespaced, {string|number} multiple, {Foo~bar} class-specific callback + [a-zA-Z_$]+ + (?: + (?: + [\\w$]* + (?:\\[\\])? # {(string|number[])} type application, a string or an array of numbers + ) | + \\.?<[\\w$]+(?:,\\s+[\\w$]+)*> # {Array} or {Object} type application (optional .) + ) + )* + \\) | [a-zA-Z_$]+ (?: (?: [\\w$]* - (?:\\[\\])? # {(string|number[])} type application, a string or an array of numbers + (?:\\[\\])? # {(string|number[])} type application, a string or an array of numbers ) | - \\.?<[\\w$]+(?:,\\s+[\\w$]+)*> # {Array} or {Object} type application (optional .) + \\.?<[\\w$]+(?:,\\s+[\\w$]+)*> # {Array} or {Object} type application (optional .) ) - )* - \\) | - [a-zA-Z_$]+ - (?: - (?: - [\\w$]* - (?:\\[\\])? # {string[]|number} type application, an array of strings or a number - ) | - \\.?<[\\w$]+(?:,\\s+[\\w$]+)*> # {Array} or {Object} type application (optional .) - ) - (?: - [\\.|~] # {Foo.bar} namespaced, {string|number} multiple, {Foo~bar} class-specific callback - [a-zA-Z_$]+ - (?: - [\\w$]* | - \\.?<[\\w$]+(?:,\\s+[\\w$]+)*> # {Array} or {Object} type application (optional .) + (?: + [\\.|~] # {Foo.bar} namespaced, {string|number} multiple, {Foo~bar} class-specific callback + [a-zA-Z_$]+ + (?: + [\\w$]* | + \\.?<[\\w$]+(?:,\\s+[\\w$]+)*> # {Array} or {Object} type application (optional .) + ) + )* ) - )* + ) + # Check for suffix + (?:\\[\\])? # {string[]} type application, an array of strings + =? # {string=} optional parameter ) - # Check for suffix - (?:\\[\\])? # {string[]} type application, an array of strings - =? # {string=} optional parameter )}) + \\s+ + ( \\[ # [foo] optional parameter \\s* (?: [a-zA-Z_$][\\w$]* (?: - (?:\\[\\])? # Foo[].bar properties within an array + (?:\\[\\])? # Foo[].bar properties within an array \\. # Foo.Bar namespaced parameter [a-zA-Z_$][\\w$]* )* (?: \\s* - = # [foo=bar] Default parameter value + = # [foo=bar] Default parameter value \\s* [\\w$\\s]* )? @@ -3094,14 +3324,17 @@ repository: (?: [a-zA-Z_$][\\w$]* (?: - (?:\\[\\])? # Foo[].bar properties within an array + (?:\\[\\])? # Foo[].bar properties within an array \\. # Foo.Bar namespaced parameter [a-zA-Z_$][\\w$]* )* )? ) + \\s+ - (?:-\\s+)? # optional hyphen before the description + + (?:-\\s+)? # optional hyphen before the description + ((?:(?!\\*\\/).)*) # The type description ''' captures: @@ -3117,53 +3350,81 @@ repository: { match: ''' (?x) + ({(?: \\* | # {*} any type \\? | # {?} unknown type - (?: # Check for a prefix - \\? | # {?string} nullable type - ! | # {!string} non-nullable type - \\.{3} # {...string} variable number of parameters - )? - (?: - \\( # Opening bracket of multiple types with parenthesis {(string|number)} - [a-zA-Z_$]+ + (?: # Check for a prefix + \\? | # {?string} nullable type + ! | # {!string} non-nullable type + \\.{3} # {...string} variable number of parameters + )? + + (?: (?: - [\\w$]* | - \\.?<[\\w$]+(?:,\\s+[\\w$]+)*> # {Array} or {Object} type application (optional .) - ) + function # {function(string, number)} function type + \\s* + \\( + \\s* + (?: + [a-zA-Z_$][\\w$]* + (?: + \\s*,\\s* + [a-zA-Z_$][\\w$]* + )* + )? + \\s* + \\) + (?: # {function(): string} function return type + \\s*:\\s* + [a-zA-Z_$][\\w$]* + )? + )? + | (?: - [\\.|~] # {Foo.bar} namespaced, {string|number} multiple, {Foo~bar} class-specific callback + \\( # Opening bracket of multiple types with parenthesis {(string|number)} + [a-zA-Z_$]+ + (?: + [\\w$]* | + \\.?<[\\w$]+(?:,\\s+[\\w$]+)*> # {Array} or {Object} type application (optional .) + ) + (?: + [\\.|~] # {Foo.bar} namespaced, {string|number} multiple, {Foo~bar} class-specific callback + [a-zA-Z_$]+ + (?: + [\\w$]* | + \\.?<[\\w$]+(?:,\\s+[\\w$]+)*> # {Array} or {Object} type application (optional .) + ) + )* + \\) | [a-zA-Z_$]+ (?: [\\w$]* | - \\.?<[\\w$]+(?:,\\s+[\\w$]+)*> # {Array} or {Object} type application (optional .) + \\.?<[\\w$]+(?:,\\s+[\\w$]+)*> # {Array} or {Object} type application (optional .) ) - )* - \\) | - [a-zA-Z_$]+ - (?: - [\\w$]* | - \\.?<[\\w$]+(?:,\\s+[\\w$]+)*> # {Array} or {Object} type application (optional .) - ) - (?: - [\\.|~] # {Foo.bar} namespaced, {string|number} multiple, {Foo~bar} class-specific callback - [a-zA-Z_$]+ - (?: - [\\w$]* | - \\.?<[\\w$]+(?:,\\s+[\\w$]+)*> # {Array} or {Object} type application (optional .) + (?: + [\\.|~] # {Foo.bar} namespaced, {string|number} multiple, {Foo~bar} class-specific callback + [a-zA-Z_$]+ + (?: + [\\w$]* | + \\.?<[\\w$]+(?:,\\s+[\\w$]+)*> # {Array} or {Object} type application (optional .) + ) + )* ) - )* + ) + # Check for suffix + (?:\\[\\])? # {string[]} type application, an array of strings + =? # {string=} optional parameter ) - # Check for suffix - (?:\\[\\])? # {string[]} type application, an array of strings - =? # {string=} optional parameter )}) + \\s+ + (?:-\\s+)? # optional hyphen before the description - ((?:(?!\\*\\/).)*) # The type description + + ((?:(?!\\*\\/).)*) # The type description ''' captures: "0": @@ -3253,8 +3514,8 @@ repository: ] "jsx-evaluated-code": name: "meta.embedded.expression.tsx" - begin: "{" - end: "}" + begin: "\\{" + end: "\\}" beginCaptures: "0": name: "punctuation.section.embedded.begin.tsx" @@ -3296,7 +3557,7 @@ repository: "jsx-tag-in-expression": begin: ''' (?x) - (?<=[({\\[,?=>]|&&|\\|\\||\\?|\\Wreturn|^return|\\Wdefault|^)\\s* + (?<=[({\\[,?=>:*]|&&|\\|\\||\\?|\\Wreturn|^return|\\Wdefault|^)\\s* (?!(<)\\s*([_$a-zA-Z][-$\\w.]*(?)) #look ahead is not start of tag without attributes (?!<\\s*[_$[:alpha:]][_$[:alnum:]]*((\\s+extends\\s+[^=>])|,)) # look ahead is not type parameter of arrow (?=(<)\\s* diff --git a/package.json b/package.json index c8eb4f03d..5a56e7ff9 100644 --- a/package.json +++ b/package.json @@ -54,7 +54,7 @@ "atom-space-pen-views": "^2.0.4", "babel": "^5.6.23", "basarat-text-buffer": "6.0.0", - "byots": "2.2.0-dev.20161117.23.11", + "byots": "2.2.0-dev.20161129.23.20", "d3": "^3.5.5", "detect-indent": "^4.0.0", "detect-newline": "^2.1.0", @@ -70,7 +70,7 @@ "react": "^0.13.3", "season": "^5.1.4", "tsconfig": "^2.2.0", - "typescript": "2.2.0-dev.20161118", + "typescript": "2.2.0-dev.20161130", "xtend": "^4.0.0" }, "devDependencies": { From db2e62c863d6680319ff5e02e168804209677886 Mon Sep 17 00:00:00 2001 From: Guntars Asmanis-Graham Date: Wed, 30 Nov 2016 13:56:29 -0500 Subject: [PATCH 11/70] Map between filePaths and editors --- dist/client/client.js | 5 +- dist/client/clientResolver.js | 71 ++++---- dist/linter.js | 25 +-- dist/main/atom/atomUtils.js | 2 +- dist/main/atom/autoCompleteProvider.js | 47 ++--- dist/main/atom/commands/commands.js | 52 +++--- dist/main/atom/tooltipManager.js | 31 ++-- dist/main/atomts.js | 236 +++++++++++++++---------- dist/worker/parent.js | 16 +- lib/client/client.ts | 6 +- lib/client/clientResolver.ts | 98 ++++------ lib/globals.ts | 5 - lib/linter.ts | 60 ++++--- lib/main/atom/atomUtils.ts | 6 +- lib/main/atom/autoCompleteProvider.ts | 18 +- lib/main/atom/commands/commands.ts | 54 +++--- lib/main/atom/tooltipManager.ts | 31 ++-- lib/main/atomts.ts | 90 +++++----- lib/typings/atompromise.d.ts | 99 ----------- lib/worker/lib/workerLib.ts | 4 +- lib/worker/parent.ts | 17 +- 21 files changed, 435 insertions(+), 538 deletions(-) delete mode 100644 lib/typings/atompromise.d.ts diff --git a/dist/client/client.js b/dist/client/client.js index 30d2b0308..a3d19577b 100644 --- a/dist/client/client.js +++ b/dist/client/client.js @@ -8,7 +8,7 @@ var child_process_1 = require("child_process"); var stream_1 = require("stream"); var byline = require("byline"); var TypescriptServiceClient = (function () { - function TypescriptServiceClient(tsServerPath, tsServerVersion) { + function TypescriptServiceClient(tsServerPath) { var _this = this; this.callbacks = {}; this.listeners = {}; @@ -34,7 +34,6 @@ var TypescriptServiceClient = (function () { } }; this.tsServerPath = tsServerPath; - this.tsServerVersion = tsServerVersion; } TypescriptServiceClient.prototype.executeChange = function (args) { this.execute("change", args); @@ -140,12 +139,12 @@ var TypescriptServiceClient = (function () { }; return TypescriptServiceClient; }()); -exports.TypescriptServiceClient = TypescriptServiceClient; TypescriptServiceClient.commandWithResponse = { completions: true, projectInfo: true, quickinfo: true }; +exports.TypescriptServiceClient = TypescriptServiceClient; function isEvent(res) { return res.type === "event"; } diff --git a/dist/client/clientResolver.js b/dist/client/clientResolver.js index b60100ab3..378641752 100644 --- a/dist/client/clientResolver.js +++ b/dist/client/clientResolver.js @@ -1,58 +1,46 @@ "use strict"; -var findServer_1 = require("./findServer"); +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 client_1 = require("./client"); +var events = require("events"); var path = require("path"); var nodeResolve = require("resolve"); var defaultServerPath = require.resolve("typescript/bin/tsserver"); -var defaultServerVersion = require("typescript/package.json").version; -var defaultServer = new client_1.TypescriptServiceClient(defaultServerPath, defaultServerVersion); -var ClientResolver = (function () { +var ClientResolver = (function (_super) { + __extends(ClientResolver, _super); function ClientResolver() { - this.clients = []; + var _this = _super.apply(this, arguments) || this; + _this.clients = {}; + return _this; } ClientResolver.prototype.get = function (filePath) { - var client = this.clients.find(function (client) { return filePath.startsWith(client.prefix); }); - if (client) { - return Promise.resolve(client.client); - } - return this.resolveFrom(filePath); - }; - ClientResolver.prototype.addClient = function (prefix, client) { - var existingClient = this.clients.find(function (client) { return client.prefix === prefix; }); - if (existingClient) { - return; - } - this.clients.push({ - prefix: prefix, - client: client - }); - if (!client.serverPromise) { - client.startServer(); - } - this.clients.sort(function (a, b) { return a.prefix.length - b.prefix.length; }); - }; - ClientResolver.prototype.resolveFrom = function (filePath) { var _this = this; - var basedir = path.dirname(filePath); - return resolveLocalServer(basedir) - .then(function (tsServerPath) { return path.resolve(tsServerPath, "..", "..", "..", ".."); }) - .then(findServer_1.findTypescriptServers) - .then(function (servers) { - console.log("got some servers", servers); - for (var _i = 0, servers_1 = servers; _i < servers_1.length; _i++) { - var server = servers_1[_i]; - _this.addClient(server.prefix, new client_1.TypescriptServiceClient(server.binPath, server.version)); + return resolveServer(filePath) + .catch(function () { return defaultServerPath; }) + .then(function (serverPath) { + if (_this.clients[serverPath]) { + return _this.clients[serverPath].client; } - return _this.get(filePath); - }).catch(function () { - _this.addClient(basedir, defaultServer); - return defaultServer; + var entry = _this.clients[serverPath] = { + client: new client_1.TypescriptServiceClient(serverPath), + pending: [], + }; + entry.client.startServer(); + entry.client.on("pendingRequestsChange", function (pending) { + entry.pending = pending; + _this.emit("pendingRequestsChange"); + }); + return entry.client; }); }; return ClientResolver; -}()); +}(events.EventEmitter)); exports.ClientResolver = ClientResolver; -function resolveLocalServer(basedir) { +function resolveServer(sourcePath) { + var basedir = path.dirname(sourcePath); return new Promise(function (resolve, reject) { nodeResolve("typescript/bin/tsserver", { basedir: basedir }, function (err, resolvedPath) { if (err) { @@ -64,3 +52,4 @@ function resolveLocalServer(basedir) { }); }); } +exports.resolveServer = resolveServer; diff --git a/dist/linter.js b/dist/linter.js index 11f47aeeb..ebac46336 100644 --- a/dist/linter.js +++ b/dist/linter.js @@ -1,7 +1,5 @@ "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'], @@ -13,27 +11,6 @@ exports.provider = { || !fs.existsSync(textEditor.buffer.file.path)) return Promise.resolve([]); var filePath = textEditor.buffer.file.path; - parent.client.executeGetErr({ files: [filePath], delay: 100 }); - return new Promise(function (resolve, reject) { - var unsub = parent.client.on("semanticDiag", function (result) { - if (result.file === filePath) { - try { - unsub(); - var errors = result.diagnostics.map(function (diag) { - return { - type: "Error", - filePath: filePath, - text: diag.text, - range: new atom_1.Range([diag.start.line - 1, diag.start.offset - 1], [diag.end.line - 1, diag.end.offset - 1]) - }; - }); - resolve(errors); - } - catch (error) { - resolve([]); - } - } - }); - }); + return Promise.resolve([]); } }; diff --git a/dist/main/atom/atomUtils.js b/dist/main/atom/atomUtils.js index 01e5bfc90..633e8e027 100644 --- a/dist/main/atom/atomUtils.js +++ b/dist/main/atom/atomUtils.js @@ -83,7 +83,7 @@ function getEditorsForAllPaths(filePaths) { 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); + editors.forEach(function (editor) { return addConsistentlyToMap(editor); }); return map; }); } diff --git a/dist/main/atom/autoCompleteProvider.js b/dist/main/atom/autoCompleteProvider.js index c85fe3927..2a4995013 100644 --- a/dist/main/atom/autoCompleteProvider.js +++ b/dist/main/atom/autoCompleteProvider.js @@ -65,31 +65,32 @@ exports.provider = { return Promise.resolve([]); } } - var promisedSuggestions = parent.client.executeCompletions({ - file: filePath, - prefix: options.prefix, - line: options.bufferPosition.row + 1, - offset: options.bufferPosition.column + 1 - }).then(function (resp) { - console.log("prefix", options.prefix); - var completionList = resp.body; - var suggestions = completionList.map(function (c) { - var prefix = options.prefix; - if (c.name && c.name.startsWith('$')) { - prefix = "$" + prefix; - } - return { - text: c.name, - replacementPrefix: prefix.trim(), - rightLabel: c.name, - leftLabel: c.kind, - type: atomUtils.kindToType(c.kind), - description: null, - }; + return parent.clients.get(filePath).then(function (client) { + return client.executeCompletions({ + file: filePath, + prefix: options.prefix, + line: options.bufferPosition.row + 1, + offset: options.bufferPosition.column + 1 + }).then(function (resp) { + console.log("prefix", options.prefix); + var completionList = resp.body; + var suggestions = completionList.map(function (c) { + var prefix = options.prefix; + if (c.name && c.name.startsWith('$')) { + prefix = "$" + prefix; + } + return { + text: c.name, + replacementPrefix: prefix.trim(), + rightLabel: c.name, + leftLabel: c.kind, + type: atomUtils.kindToType(c.kind), + description: null, + }; + }); + return suggestions; }); - return suggestions; }); - return promisedSuggestions; } }, }; diff --git a/dist/main/atom/commands/commands.js b/dist/main/atom/commands/commands.js index a38e50e2e..a006ec803 100644 --- a/dist/main/atom/commands/commands.js +++ b/dist/main/atom/commands/commands.js @@ -251,31 +251,33 @@ function registerCommands() { var cursor = editor.getLastCursor(); var position = cursor.getBufferPosition(); var filePath = editor.getPath(); - parent.client.executeQuickInfo({ - file: filePath, - line: position.row + 1, - offset: position.column + 1 - }).then(function (_a) { - var _b = _a.body, displayString = _b.displayString, documentation = _b.documentation; - var decoration = editor.decorateMarker(cursor.getMarker(), { - type: 'overlay', - item: typeOverlayView_1.create(displayString, documentation) - }); - 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); - }).catch(function () { }); + parent.clients.get(filePath).then(function (client) { + return client.executeQuickInfo({ + file: filePath, + line: position.row + 1, + offset: position.column + 1 + }).then(function (_a) { + var _b = _a.body, displayString = _b.displayString, documentation = _b.documentation; + var decoration = editor.decorateMarker(cursor.getMarker(), { + type: 'overlay', + item: typeOverlayView_1.create(displayString, documentation) + }); + 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); + }).catch(function () { }); + }); }); atom.commands.add('atom-workspace', 'typescript:go-to-next', function (e) { gotoHistory.gotoNext(); diff --git a/dist/main/atom/tooltipManager.js b/dist/main/atom/tooltipManager.js index 3a180dd85..98b855110 100644 --- a/dist/main/atom/tooltipManager.js +++ b/dist/main/atom/tooltipManager.js @@ -25,6 +25,7 @@ function attach(editorView, editor) { if (!fs.existsSync(filePath)) { return; } + var clientPromise = parent.clients.get(filePath); var scroll = getFromShadowDom(editorView, '.scroll-view'); var subscriber = new Subscriber(); var exprTypeTimeout = null; @@ -63,20 +64,22 @@ function attach(editorView, editor) { bottom: e.clientY + offset }; exprTypeTooltip = new TooltipView(tooltipRect); - parent.client.executeQuickInfo({ - file: filePath, - line: bufferPt.row + 1, - offset: bufferPt.column + 1 - }).then(function (_a) { - var _b = _a.body, displayString = _b.displayString, documentation = _b.documentation; - var message = "" + escape(displayString) + ""; - if (documentation) { - message = message + ("
" + escape(documentation).replace(/(?:\r\n|\r|\n)/g, '
') + "
"); - } - if (exprTypeTooltip) { - exprTypeTooltip.updateText(message); - } - }, function () { }); + clientPromise.then(function (client) { + client.executeQuickInfo({ + file: filePath, + line: bufferPt.row + 1, + offset: bufferPt.column + 1 + }).then(function (_a) { + var _b = _a.body, displayString = _b.displayString, documentation = _b.documentation; + var message = "" + escape(displayString) + ""; + if (documentation) { + message = message + ("
" + escape(documentation).replace(/(?:\r\n|\r|\n)/g, '
') + "
"); + } + if (exprTypeTooltip) { + exprTypeTooltip.updateText(message); + } + }, function () { }); + }); } function deactivate() { subscriber.unsubscribe(); diff --git a/dist/main/atomts.js b/dist/main/atomts.js index c95d4633f..d33127b5e 100644 --- a/dist/main/atomts.js +++ b/dist/main/atomts.js @@ -1,4 +1,39 @@ "use strict"; +var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) { + return new (P || (P = Promise))(function (resolve, reject) { + function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } } + function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } } + function step(result) { result.done ? resolve(result.value) : new P(function (resolve) { resolve(result.value); }).then(fulfilled, rejected); } + step((generator = generator.apply(thisArg, _arguments)).next()); + }); +}; +var __generator = (this && this.__generator) || function (thisArg, body) { + var _ = { label: 0, sent: function() { if (t[0] & 1) throw t[1]; return t[1]; }, trys: [], ops: [] }, f, y, t; + return { next: verb(0), "throw": verb(1), "return": verb(2) }; + function verb(n) { return function (v) { return step([n, v]); }; } + function step(op) { + if (f) throw new TypeError("Generator is already executing."); + while (_) try { + if (f = 1, y && (t = y[op[0] & 2 ? "return" : op[0] ? "throw" : "next"]) && !(t = t.call(y, op[1])).done) return t; + if (y = 0, t) op = [0, t.value]; + switch (op[0]) { + case 0: case 1: t = op; break; + case 4: _.label++; return { value: op[1], done: false }; + case 5: _.label++; y = op[1]; op = [0]; continue; + case 7: op = _.ops.pop(); _.trys.pop(); continue; + default: + if (!(t = _.trys, t = t.length > 0 && t[t.length - 1]) && (op[0] === 6 || op[0] === 2)) { _ = 0; continue; } + if (op[0] === 3 && (!t || (op[1] > t[0] && op[1] < t[3]))) { _.label = op[1]; break; } + if (op[0] === 6 && _.label < t[1]) { _.label = t[1]; t = op; break; } + if (t && _.label < t[2]) { _.label = t[2]; _.ops.push(op); break; } + if (t[2]) _.ops.pop(); + _.trys.pop(); continue; + } + op = body.call(thisArg, _); + } catch (e) { op = [6, e]; y = 0; } finally { f = t = 0; } + if (op[0] & 5) throw op[1]; return { value: op[0] ? op[1] : void 0, done: true }; + } +}; var atomConfig = require("./atom/atomConfig"); var makeTypeScriptGlobal_1 = require("../typescript/makeTypeScriptGlobal"); makeTypeScriptGlobal_1.makeTsGlobal(atomConfig.typescriptServices); @@ -60,103 +95,118 @@ function readyToActivate() { } }); editorWatch = atom.workspace.observeTextEditors(function (editor) { - var filePath = editor.getPath(); - console.log("opened editor", filePath); - var editorView = atom_space_pen_views_1.$(atom.views.getView(editor)); - tooltipManager.attach(editorView, editor); - var unsubSyntax = parent.client.on("syntaxDiag", function (diag) { - }); - var unsubSemantic = parent.client.on("semanticDiag", function (diag) { - if (diag.file === filePath) { - console.log("semantic errors", diag); - mainPanelView_1.errorView.setErrors(filePath, diag.diagnostics.map(function (error) { - var preview = editor.buffer.getTextInRange(new _atom.Range([error.start.line - 1, error.start.offset - 1], [error.end.line - 1, error.end.offset - 1])); - return { - filePath: filePath, - startPos: { line: error.start.line - 1, col: error.start.offset - 1 }, - endPos: { line: error.end.line - 1, col: error.end.offset - 1 }, - message: ts.flattenDiagnosticMessageText(error.text, '\n'), - preview: preview - }; - })); - } - }); - var ext = path.extname(filePath); - if (atomUtils.isAllowedExtension(ext)) { - var isTst = ext === '.tst'; - try { - onlyOnceStuff(); - parent.client.executeOpen({ - file: filePath, - fileContent: editor.getText() - }); - updatePanelConfig(filePath); - var onDisk = false; - if (fs.existsSync(filePath)) { - onDisk = true; + return __awaiter(this, void 0, void 0, function () { + var filePath, client, editorView, ext, unsubSyntax_1, unsubSemantic_1, isTst, onDisk, changeObserver, buffer, fasterChangeObserver, saveObserver, destroyObserver; + return __generator(this, function (_a) { + switch (_a.label) { + case 0: + filePath = editor.getPath(); + console.log("opened editor", filePath); + return [4 /*yield*/, parent.clients.get(filePath)]; + case 1: + client = _a.sent(); + console.log("found client for editor", { filePath: filePath, client: client }); + editorView = atom_space_pen_views_1.$(atom.views.getView(editor)); + tooltipManager.attach(editorView, editor); + ext = path.extname(filePath); + if (atomUtils.isAllowedExtension(ext)) { + unsubSyntax_1 = client.on("syntaxDiag", function (diag) { + }); + unsubSemantic_1 = client.on("semanticDiag", function (diag) { + if (diag.file === filePath) { + console.log("semantic errors", diag); + mainPanelView_1.errorView.setErrors(filePath, diag.diagnostics.map(function (error) { + var preview = editor.buffer.getTextInRange(new _atom.Range([error.start.line - 1, error.start.offset - 1], [error.end.line - 1, error.end.offset - 1])); + return { + filePath: filePath, + startPos: { line: error.start.line - 1, col: error.start.offset - 1 }, + endPos: { line: error.end.line - 1, col: error.end.offset - 1 }, + message: ts.flattenDiagnosticMessageText(error.text, '\n'), + preview: preview + }; + })); + } + }); + isTst = ext === '.tst'; + try { + onlyOnceStuff(); + client.executeOpen({ + file: filePath, + fileContent: editor.getText() + }); + updatePanelConfig(filePath); + onDisk = false; + if (fs.existsSync(filePath)) { + onDisk = true; + } + hideIfNotActiveOnStart(); + debugAtomTs.runDebugCode({ filePath: filePath, editor: editor }); + if (onDisk) { + client.executeGetErr({ files: [filePath], delay: 100 }); + } + editorSetup.setupEditor(editor); + 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; + } + client.executeGetErr({ files: [filePath], delay: 100 }); + }); + buffer = editor.buffer; + fasterChangeObserver = editor.buffer.onDidChange(function (diff) { + client.executeChange({ + endLine: diff.oldRange.end.row + 1, + endOffset: diff.oldRange.end.column + 1, + file: editor.getPath(), + line: diff.oldRange.start.row + 1, + offset: diff.oldRange.start.column + 1, + insertString: diff.newText, + }); + }); + saveObserver = editor.onDidSave(function (event) { + console.log("saved", editor.getPath()); + onDisk = true; + filePath = event.path; + }); + destroyObserver = editor.onDidDestroy(function () { + client.executeClose({ file: editor.getPath() }); + mainPanelView_1.errorView.setErrors(filePath, []); + changeObserver.dispose(); + fasterChangeObserver.dispose(); + saveObserver.dispose(); + destroyObserver.dispose(); + unsubSemantic_1(); + unsubSyntax_1(); + }); + } + catch (ex) { + console.error('Solve this in atom-typescript', ex); + throw ex; + } + } + return [2 /*return*/]; } - hideIfNotActiveOnStart(); - debugAtomTs.runDebugCode({ filePath: filePath, editor: editor }); - if (onDisk) { - parent.client.executeGetErr({ files: [filePath], delay: 100 }); - } - 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; - } - parent.client.executeGetErr({ files: [filePath], delay: 100 }); - }); - var buffer = editor.buffer; - var fasterChangeObserver = editor.buffer.onDidChange(function (diff) { - parent.client.executeChange({ - endLine: diff.oldRange.end.row + 1, - endOffset: diff.oldRange.end.column + 1, - file: editor.getPath(), - line: diff.oldRange.start.row + 1, - offset: diff.oldRange.start.column + 1, - insertString: diff.newText, - }); - }); - var saveObserver = editor.onDidSave(function (event) { - console.log("saved", editor.getPath()); - onDisk = true; - filePath = event.path; - }); - var destroyObserver = editor.onDidDestroy(function () { - parent.client.executeClose({ file: editor.getPath() }); - mainPanelView_1.errorView.setErrors(filePath, []); - changeObserver.dispose(); - fasterChangeObserver.dispose(); - saveObserver.dispose(); - destroyObserver.dispose(); - unsubSemantic(); - unsubSyntax(); - }); - } - catch (ex) { - console.error('Solve this in atom-typescript', ex); - throw ex; - } - } + }); + }); }); commands.registerCommands(); } -function updatePanelConfig(file) { - parent.client.executeProjectInfo({ - needFileNameList: false, - file: file - }).then(function (result) { - mainPanelView.panelView.setTsconfigInUse(result.body.configFileName); - }, function (err) { - mainPanelView.panelView.setTsconfigInUse(''); +function updatePanelConfig(filePath) { + parent.clients.get(filePath).then(function (client) { + client.executeProjectInfo({ + needFileNameList: false, + file: filePath + }).then(function (result) { + mainPanelView.panelView.setTsconfigInUse(result.body.configFileName); + }, function (err) { + mainPanelView.panelView.setTsconfigInUse(''); + }); }); } function activate(state) { diff --git a/dist/worker/parent.js b/dist/worker/parent.js index 300ae76ec..783211096 100644 --- a/dist/worker/parent.js +++ b/dist/worker/parent.js @@ -3,7 +3,7 @@ var debug_1 = require("./debug"); var tsconfig = require("tsconfig/dist/tsconfig"); var workerLib = require("./lib/workerLib"); var atomConfig = require("../main/atom/atomConfig"); -var client_1 = require("../client/client"); +var clientResolver_1 = require("../client/clientResolver"); var parent = new workerLib.Parent(); var mainPanel = require("../main/atom/views/mainPanelView"); if (debug_1.debugSync) { @@ -73,15 +73,19 @@ exports.createProject = parent.sendToIpc(projectService.createProject); exports.toggleBreakpoint = parent.sendToIpc(projectService.toggleBreakpoint); var queryParent = require("./queryParent"); parent.registerAllFunctionsExportedFromAsResponders(queryParent); -exports.client = new client_1.TypescriptServiceClient("haha", "Hehe"); -exports.client.on("pendingRequestsChange", function (pending) { +exports.clients = new clientResolver_1.ClientResolver(); +exports.clients.on("pendingRequestsChange", function () { if (!mainPanel.panelView) return; - mainPanel.panelView.updatePendingRequests(pending); + var pending = Object.keys(exports.clients.clients) + .map(function (serverPath) { return exports.clients.clients[serverPath].pending; }); + mainPanel.panelView.updatePendingRequests([].concat.apply([], pending)); }); function loadProjectConfig(sourcePath) { - return exports.client.executeProjectInfo({ needFileNameList: false, file: sourcePath }).then(function (result) { - return tsconfig.load(result.body.configFileName); + return exports.clients.get(sourcePath).then(function (client) { + return client.executeProjectInfo({ needFileNameList: false, file: sourcePath }).then(function (result) { + return tsconfig.load(result.body.configFileName); + }); }); } exports.loadProjectConfig = loadProjectConfig; diff --git a/lib/client/client.ts b/lib/client/client.ts index 5c6deaea3..5a3be8312 100644 --- a/lib/client/client.ts +++ b/lib/client/client.ts @@ -32,12 +32,8 @@ export class TypescriptServiceClient { /** Path to the tsserver executable */ readonly tsServerPath: string - /** Version of the tsserver */ - readonly tsServerVersion: string - - constructor(tsServerPath: string, tsServerVersion: string) { + constructor(tsServerPath: string) { this.tsServerPath = tsServerPath - this.tsServerVersion = tsServerVersion } static commandWithResponse = { diff --git a/lib/client/clientResolver.ts b/lib/client/clientResolver.ts index c6a454999..36b95bc39 100644 --- a/lib/client/clientResolver.ts +++ b/lib/client/clientResolver.ts @@ -1,79 +1,52 @@ -import {findTypescriptServers} from "./findServer" -import {TypescriptServiceClient} from "./client" +import {TypescriptServiceClient as Client} from "./client" +import * as events from "events" import * as fs from "fs" import * as path from "path" import * as nodeResolve from "resolve" const defaultServerPath = require.resolve("typescript/bin/tsserver") -const defaultServerVersion = require("typescript/package.json").version -const defaultServer = new TypescriptServiceClient(defaultServerPath, defaultServerVersion) /** * 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 { - clients: { - prefix: string, - client: TypescriptServiceClient - }[] = [] - - get(filePath: string): Promise { - const client = this.clients.find(client => filePath.startsWith(client.prefix)) - - if (client) { - return Promise.resolve(client.client) - } - - // If we didn't find a client in the clients array, we need to resolve, start and add a new one - return this.resolveFrom(filePath) - } - - private addClient(prefix: string, client: TypescriptServiceClient) { - const existingClient = this.clients.find(client => client.prefix === prefix) - - if (existingClient) { - return - } - - this.clients.push({ - prefix, - client - }) +export class ClientResolver extends events.EventEmitter { - if (!client.serverPromise) { - client.startServer() + clients: { + [tsServerPath: string]: { + client: Client, + pending: string[], } + } = {} + + get(filePath: string): Promise { + return resolveServer(filePath) + .catch(() => defaultServerPath) + .then(serverPath => { + if (this.clients[serverPath]) { + return this.clients[serverPath].client + } - // Sort the clients in the descending order of the prefix length - this.clients.sort((a, b) => a.prefix.length - b.prefix.length) - } - - private resolveFrom(filePath: string): Promise { - const basedir = path.dirname(filePath) - - return resolveLocalServer(basedir) - .then(tsServerPath => path.resolve(tsServerPath, "..", "..", "..", "..")) - .then(findTypescriptServers) - .then(servers => { - console.log("got some servers", servers) - - for (const server of servers) { - this.addClient(server.prefix, new TypescriptServiceClient(server.binPath, server.version)) + const entry = this.clients[serverPath] = { + client: new Client(serverPath), + pending: [], } - // - return this.get(filePath) + entry.client.startServer() - }).catch(() => { - // TODO: Ensure there are no nested servers under the basedir too - this.addClient(basedir, defaultServer) - return defaultServer - }) + entry.client.on("pendingRequestsChange", pending => { + entry.pending = pending + this.emit("pendingRequestsChange") + }) + + return entry.client + }) } } -function resolveLocalServer(basedir: string): Promise { +export function resolveServer(sourcePath: string): Promise { + const basedir = path.dirname(sourcePath) + return new Promise((resolve, reject) => { nodeResolve("typescript/bin/tsserver", {basedir}, (err, resolvedPath) => { if (err) { @@ -84,14 +57,3 @@ function resolveLocalServer(basedir: string): Promise { }) }) } - -// /** Given a start directory, try to resolve tsserver executable from node_modules */ -// export function findTSServer(basedir: string): string { -// const tsPath = resolve.sync("typescript/package.json", {basedir}) -// const tsServerPath = path.resolve(path.dirname(tsPath), "bin", "tsserver") -// -// // This will throw if the file does not exist on the disk -// fs.statSync(tsServerPath) -// -// return tsServerPath -// } diff --git a/lib/globals.ts b/lib/globals.ts index de4e878ea..6133df676 100644 --- a/lib/globals.ts +++ b/lib/globals.ts @@ -8,7 +8,6 @@ /// /// -/// /** Utility function to print stack trace from whereever */ declare function stack(); @@ -19,10 +18,6 @@ declare module NodeJS { } } -interface Function { - name?: string; // exists for named function on node / atom / "good" browsers ;) -} - interface Error { details?: any; // Really useful to have for debugging } diff --git a/lib/linter.ts b/lib/linter.ts index e71944a9b..a8abc6e01 100644 --- a/lib/linter.ts +++ b/lib/linter.ts @@ -32,34 +32,36 @@ export var provider = { var filePath = textEditor.buffer.file.path; - // Trigger an error check - parent.client.executeGetErr({files: [filePath], delay: 100}) - - return new Promise((resolve, reject) => { - - // Listen for a semanticDiag message for this specific file, unsub and resolve - const unsub = parent.client.on("semanticDiag", result => { - if (result.file === filePath) { - try { - unsub() - - const errors: LinterMessage[] = result.diagnostics.map(diag => { - return { - type: "Error", - filePath, - text: diag.text, - range: new Range( - [diag.start.line-1, diag.start.offset-1], - [diag.end.line-1, diag.end.offset-1]) - } - }) - - resolve(errors) - } catch (error) { - resolve([]) - } - } - }) - }) + return Promise.resolve([]) + + // // Trigger an error check + // parent.client.executeGetErr({files: [filePath], delay: 100}) + // + // return new Promise((resolve, reject) => { + // + // // Listen for a semanticDiag message for this specific file, unsub and resolve + // const unsub = parent.client.on("semanticDiag", result => { + // if (result.file === filePath) { + // try { + // unsub() + // + // const errors: LinterMessage[] = result.diagnostics.map(diag => { + // return { + // type: "Error", + // filePath, + // text: diag.text, + // range: new Range( + // [diag.start.line-1, diag.start.offset-1], + // [diag.end.line-1, diag.end.offset-1]) + // } + // }) + // + // resolve(errors) + // } catch (error) { + // resolve([]) + // } + // } + // }) + // }) } } diff --git a/lib/main/atom/atomUtils.ts b/lib/main/atom/atomUtils.ts index e50ab1cfd..2534b157a 100644 --- a/lib/main/atom/atomUtils.ts +++ b/lib/main/atom/atomUtils.ts @@ -88,10 +88,10 @@ 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; }); diff --git a/lib/main/atom/autoCompleteProvider.ts b/lib/main/atom/autoCompleteProvider.ts index 149e96819..c78b690c7 100644 --- a/lib/main/atom/autoCompleteProvider.ts +++ b/lib/main/atom/autoCompleteProvider.ts @@ -147,12 +147,13 @@ export var provider: autocompleteplus.Provider = { } } - var promisedSuggestions = parent.client.executeCompletions({ - file: filePath, - prefix: options.prefix, - line: options.bufferPosition.row+1, - offset: options.bufferPosition.column+1 - }).then(resp => { + return parent.clients.get(filePath).then(client => { + return client.executeCompletions({ + file: filePath, + prefix: options.prefix, + line: options.bufferPosition.row+1, + offset: options.bufferPosition.column+1 + }).then(resp => { console.log("prefix", options.prefix) var completionList = resp.body; @@ -191,9 +192,8 @@ export var provider: autocompleteplus.Provider = { }); return suggestions; - }); - - return promisedSuggestions; + }); + }) } }, } diff --git a/lib/main/atom/commands/commands.ts b/lib/main/atom/commands/commands.ts index 5ee4360ca..7b37e7e31 100644 --- a/lib/main/atom/commands/commands.ts +++ b/lib/main/atom/commands/commands.ts @@ -328,32 +328,34 @@ export function registerCommands() { var position = cursor.getBufferPosition() var filePath = editor.getPath(); - parent.client.executeQuickInfo({ - file: filePath, - line: position.row+1, - offset: position.column+1 - }).then(({body: {displayString, documentation}}) => { - var decoration = editor.decorateMarker(cursor.getMarker(), { - type: 'overlay', - item: createTypeOverlay(displayString, documentation) - }); - - 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); - }).catch(() => { /* ignore errors */ }) + parent.clients.get(filePath).then(client => { + return client.executeQuickInfo({ + file: filePath, + line: position.row+1, + offset: position.column+1 + }).then(({body: {displayString, documentation}}) => { + var decoration = editor.decorateMarker(cursor.getMarker(), { + type: 'overlay', + item: createTypeOverlay(displayString, documentation) + }); + + 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); + }).catch(() => { /* ignore errors */ }) + }) }); atom.commands.add('atom-workspace', 'typescript:go-to-next', (e) => { diff --git a/lib/main/atom/tooltipManager.ts b/lib/main/atom/tooltipManager.ts index 9a7ce9415..0a87d316a 100644 --- a/lib/main/atom/tooltipManager.ts +++ b/lib/main/atom/tooltipManager.ts @@ -37,6 +37,7 @@ export function attach(editorView: JQuery, editor: AtomCore.IEditor) { return; } + var clientPromise = parent.clients.get(filePath) var scroll = getFromShadowDom(editorView, '.scroll-view'); var subscriber = new Subscriber(); var exprTypeTimeout = null; @@ -88,20 +89,22 @@ export function attach(editorView: JQuery, editor: AtomCore.IEditor) { }; exprTypeTooltip = new TooltipView(tooltipRect); - parent.client.executeQuickInfo({ - file: filePath, - line: bufferPt.row+1, - offset: bufferPt.column+1 - }).then(({body: {displayString, documentation}}) => { - var message = `${escape(displayString) }`; - if (documentation) { - message = message + `
${escape(documentation).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); - } - }, () => { /* ignore the errors */ }) + clientPromise.then(client => { + client.executeQuickInfo({ + file: filePath, + line: bufferPt.row+1, + offset: bufferPt.column+1 + }).then(({body: {displayString, documentation}}) => { + var message = `${escape(displayString) }`; + if (documentation) { + message = message + `
${escape(documentation).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); + } + }, () => { /* ignore the errors */ }) + }) } function deactivate() { diff --git a/lib/main/atomts.ts b/lib/main/atomts.ts index a878981e2..6aab8a5da 100644 --- a/lib/main/atomts.ts +++ b/lib/main/atomts.ts @@ -128,52 +128,56 @@ function readyToActivate() { }); // Observe editors loading - editorWatch = atom.workspace.observeTextEditors((editor: AtomCore.IEditor) => { + editorWatch = atom.workspace.observeTextEditors(async function(editor: AtomCore.IEditor) { let filePath = editor.getPath() - console.log("opened editor", filePath) + let client = await parent.clients.get(filePath) + console.log("found client for editor", {filePath, client}) + // subscribe for tooltips // inspiration : https://github.com/chaika2013/ide-haskell var editorView = $(atom.views.getView(editor)) tooltipManager.attach(editorView, editor) - // Listen for error events for this file and display them - const unsubSyntax = parent.client.on("syntaxDiag", diag => { - // console.log("syntax errors", diag) - }) - - const unsubSemantic = parent.client.on("semanticDiag", diag => { - if (diag.file === filePath) { - console.log("semantic errors", diag) - - errorView.setErrors(filePath, diag.diagnostics.map(error => { - const preview = editor.buffer.getTextInRange( - new _atom.Range( - [error.start.line-1, error.start.offset-1], - [error.end.line-1, error.end.offset-1])) - - return { - filePath: filePath, - startPos: {line: error.start.line - 1, col: error.start.offset - 1}, - endPos: {line: error.end.line - 1, col: error.end.offset - 1}, - message: ts.flattenDiagnosticMessageText(error.text, '\n'), - preview - } + var ext = path.extname(filePath); + if (atomUtils.isAllowedExtension(ext)) { + // Listen for error events for this file and display them + const unsubSyntax = client.on("syntaxDiag", diag => { + // console.log("syntax errors", diag) + }) + + const unsubSemantic = client.on("semanticDiag", diag => { + if (diag.file === filePath) { + console.log("semantic errors", diag) + + errorView.setErrors(filePath, diag.diagnostics.map(error => { + const preview = editor.buffer.getTextInRange( + new _atom.Range( + [error.start.line-1, error.start.offset-1], + [error.end.line-1, error.end.offset-1])) + + return { + filePath: filePath, + startPos: {line: error.start.line - 1, col: error.start.offset - 1}, + endPos: {line: error.end.line - 1, col: error.end.offset - 1}, + message: ts.flattenDiagnosticMessageText(error.text, '\n'), + preview + } + + + })) + } + }) - })) - } - }) - var ext = path.extname(filePath); - if (atomUtils.isAllowedExtension(ext)) { let isTst = ext === '.tst'; try { // Only once stuff onlyOnceStuff(); - parent.client.executeOpen({ + client.executeOpen({ file: filePath, fileContent: editor.getText() }) @@ -193,7 +197,7 @@ function readyToActivate() { if (onDisk) { - parent.client.executeGetErr({files: [filePath], delay: 100}) + client.executeGetErr({files: [filePath], delay: 100}) // // Set errors in project per file // parent.updateText({ filePath: filePath, text: editor.getText() }) @@ -237,7 +241,7 @@ function readyToActivate() { } // Set errors in project per file - parent.client.executeGetErr({files: [filePath], delay: 100}) + client.executeGetErr({files: [filePath], delay: 100}) // TODO: provide function completions /*var position = atomUtils.getEditorPosition(editor); @@ -262,7 +266,7 @@ function readyToActivate() { //// 20 20 "" 20 24 "aaaa" // stack(); - parent.client.executeChange({ + client.executeChange({ endLine: diff.oldRange.end.row+1, endOffset: diff.oldRange.end.column+1, file: editor.getPath(), @@ -294,7 +298,7 @@ function readyToActivate() { // Observe editors closing var destroyObserver = editor.onDidDestroy(() => { - parent.client.executeClose({file: editor.getPath()}) + client.executeClose({file: editor.getPath()}) // Clear errors in view errorView.setErrors(filePath, []); @@ -321,14 +325,16 @@ function readyToActivate() { } /** Update the panel with the configu resolved from the given source file */ -function updatePanelConfig(file: string) { - parent.client.executeProjectInfo({ - needFileNameList: false, - file - }).then(result => { - mainPanelView.panelView.setTsconfigInUse(result.body.configFileName) - }, err => { - mainPanelView.panelView.setTsconfigInUse(''); +function updatePanelConfig(filePath: string) { + parent.clients.get(filePath).then(client => { + client.executeProjectInfo({ + needFileNameList: false, + file: filePath + }).then(result => { + mainPanelView.panelView.setTsconfigInUse(result.body.configFileName) + }, err => { + mainPanelView.panelView.setTsconfigInUse(''); + }) }) } 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/worker/lib/workerLib.ts b/lib/worker/lib/workerLib.ts index 8633144e8..452cabd0f 100644 --- a/lib/worker/lib/workerLib.ts +++ b/lib/worker/lib/workerLib.ts @@ -45,11 +45,11 @@ class RequesterResponder { ///////////////////////////////// REQUESTOR ///////////////////////// - private currentListeners: { [message: string]: { [id: string]: PromiseDeferred } } = {}; + private currentListeners: { [message: string]: { [id: string]: any } } = {}; /** Only relevant when we only want the last of this type */ private currentLastOfType: { - [message: string]: { data: any; defer: PromiseDeferred; } + [message: string]: { data: any, defer: any } } = {}; private pendingRequests: string[] = []; diff --git a/lib/worker/parent.ts b/lib/worker/parent.ts index 149272018..6014eb19d 100644 --- a/lib/worker/parent.ts +++ b/lib/worker/parent.ts @@ -8,6 +8,7 @@ import * as protocol from "typescript/lib/protocol"; import * as atomConfig from "../main/atom/atomConfig"; import {TypescriptServiceClient} from "../client/client" +import {ClientResolver} from "../client/clientResolver" var parent = new workerLib.Parent(); import * as mainPanel from "../main/atom/views/mainPanelView"; @@ -99,18 +100,22 @@ export var toggleBreakpoint = parent.sendToIpc(projectService.toggleBreakpoint); import queryParent = require('./queryParent'); parent.registerAllFunctionsExportedFromAsResponders(queryParent); -// const tsserverPath = findTSServer(__dirname) -export const client = new TypescriptServiceClient("haha", "Hehe") +export const clients = new ClientResolver() -client.on("pendingRequestsChange", pending => { +clients.on("pendingRequestsChange", () => { // We only start once the panel view is initialized if (!mainPanel.panelView) return; - mainPanel.panelView.updatePendingRequests(pending); + const pending = Object.keys(clients.clients) + .map(serverPath => clients.clients[serverPath].pending) + + mainPanel.panelView.updatePendingRequests([].concat.apply([], pending)) }) export function loadProjectConfig(sourcePath: string): Promise { - return client.executeProjectInfo({needFileNameList: false, file: sourcePath}).then(result => { - return tsconfig.load(result.body.configFileName) + return clients.get(sourcePath).then(client => { + return client.executeProjectInfo({needFileNameList: false, file: sourcePath}).then(result => { + return tsconfig.load(result.body.configFileName) + }) }) } From 967cbce8c988eb2ccd52ef6217a5aab43472f94e Mon Sep 17 00:00:00 2001 From: Guntars Asmanis-Graham Date: Wed, 30 Nov 2016 14:42:18 -0500 Subject: [PATCH 12/70] Add tslib and use importHelpers --- dist/client/client.js | 8 +- dist/client/clientResolver.js | 8 +- dist/main/atom/autoCompleteProvider.js | 107 +++++----- dist/main/atom/components/ts-view.js | 8 +- dist/main/atom/typescriptGrammar.js | 8 +- dist/main/atom/views/astView.js | 8 +- dist/main/atom/views/awesomePanelView.js | 8 +- dist/main/atom/views/contextView.js | 8 +- dist/main/atom/views/dependencyView.js | 8 +- dist/main/atom/views/documentationView.js | 8 +- dist/main/atom/views/fileSymbolsView.js | 8 +- dist/main/atom/views/lineMessageView.js | 8 +- dist/main/atom/views/mainPanelView.js | 8 +- dist/main/atom/views/plainMessageView.js | 8 +- dist/main/atom/views/projectSymbolsView.js | 8 +- dist/main/atom/views/rView.js | 10 +- dist/main/atom/views/renameView.js | 8 +- dist/main/atom/views/semanticView.js | 10 +- .../atom/views/simpleOverlaySelectionView.js | 8 +- dist/main/atom/views/simpleSelectionView.js | 8 +- dist/main/atom/views/tooltipView.js | 8 +- dist/main/atom/views/view.js | 10 +- dist/main/atomts.js | 40 +--- dist/worker/lib/workerLib.js | 10 +- lib/main/atom/autoCompleteProvider.ts | 185 +++++++++--------- lib/tsconfig.json | 1 + package.json | 1 + 27 files changed, 187 insertions(+), 331 deletions(-) diff --git a/dist/client/client.js b/dist/client/client.js index a3d19577b..25fbb6e21 100644 --- a/dist/client/client.js +++ b/dist/client/client.js @@ -1,9 +1,5 @@ "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 tslib_1 = require("tslib"); var child_process_1 = require("child_process"); var stream_1 = require("stream"); var byline = require("byline"); @@ -155,7 +151,7 @@ function messageStream(input) { return input.pipe(byline()).pipe(new MessageStream()); } var MessageStream = (function (_super) { - __extends(MessageStream, _super); + tslib_1.__extends(MessageStream, _super); function MessageStream() { var _this = _super.call(this, { objectMode: true }) || this; _this.lineCount = 1; diff --git a/dist/client/clientResolver.js b/dist/client/clientResolver.js index 378641752..85241a120 100644 --- a/dist/client/clientResolver.js +++ b/dist/client/clientResolver.js @@ -1,16 +1,12 @@ "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 tslib_1 = require("tslib"); var client_1 = require("./client"); var events = require("events"); var path = require("path"); var nodeResolve = require("resolve"); var defaultServerPath = require.resolve("typescript/bin/tsserver"); var ClientResolver = (function (_super) { - __extends(ClientResolver, _super); + tslib_1.__extends(ClientResolver, _super); function ClientResolver() { var _this = _super.apply(this, arguments) || this; _this.clients = {}; diff --git a/dist/main/atom/autoCompleteProvider.js b/dist/main/atom/autoCompleteProvider.js index 2a4995013..dfe27f2ba 100644 --- a/dist/main/atom/autoCompleteProvider.js +++ b/dist/main/atom/autoCompleteProvider.js @@ -1,4 +1,5 @@ "use strict"; +var tslib_1 = require("tslib"); var parent = require("../../worker/parent"); var fs = require("fs"); var atomUtils = require("./atomUtils"); @@ -27,70 +28,50 @@ exports.provider = { 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) { - 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([]); - } - } - return parent.clients.get(filePath).then(function (client) { - return client.executeCompletions({ - file: filePath, - prefix: options.prefix, - line: options.bufferPosition.row + 1, - offset: options.bufferPosition.column + 1 - }).then(function (resp) { - console.log("prefix", options.prefix); - var completionList = resp.body; - var suggestions = completionList.map(function (c) { - var prefix = options.prefix; - if (c.name && c.name.startsWith('$')) { - prefix = "$" + prefix; + return tslib_1.__awaiter(this, void 0, void 0, function () { + var filePath, client, prefix; + return tslib_1.__generator(this, function (_a) { + switch (_a.label) { + case 0: + filePath = options.editor.getPath(); + if (!filePath || !fs.existsSync(filePath)) + return [2 /*return*/, []]; + return [4 /*yield*/, parent.clients.get(filePath)]; + case 1: + client = _a.sent(); + if (explicitlyTriggered) { + explicitlyTriggered = false; } - return { - text: c.name, - replacementPrefix: prefix.trim(), - rightLabel: c.name, - leftLabel: c.kind, - type: atomUtils.kindToType(c.kind), - description: null, - }; - }); - return suggestions; - }); + else { + prefix = options.prefix.trim(); + if (prefix === '' || prefix === ';' || prefix === '{') { + return [2 /*return*/, Promise.resolve([])]; + } + } + return [2 /*return*/, client.executeCompletions({ + file: filePath, + prefix: options.prefix, + line: options.bufferPosition.row + 1, + offset: options.bufferPosition.column + 1 + }).then(function (resp) { + console.log("prefix", options.prefix); + return resp.body.map(function (c) { + var prefix = options.prefix; + if (c.name && c.name.startsWith('$')) { + prefix = "$" + prefix; + } + return { + text: c.name, + replacementPrefix: prefix === "." ? "" : prefix.trim(), + rightLabel: c.name, + leftLabel: c.kind, + type: atomUtils.kindToType(c.kind), + description: null, + }; + }); + })]; + } }); - } + }); }, }; diff --git a/dist/main/atom/components/ts-view.js b/dist/main/atom/components/ts-view.js index d8916aee8..422cdcd6f 100644 --- a/dist/main/atom/components/ts-view.js +++ b/dist/main/atom/components/ts-view.js @@ -1,11 +1,7 @@ "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 tslib_1 = require("tslib"); var TsView = (function (_super) { - __extends(TsView, _super); + tslib_1.__extends(TsView, _super); function TsView() { return _super.apply(this, arguments) || this; } diff --git a/dist/main/atom/typescriptGrammar.js b/dist/main/atom/typescriptGrammar.js index 27f98b730..2d23ca1df 100644 --- a/dist/main/atom/typescriptGrammar.js +++ b/dist/main/atom/typescriptGrammar.js @@ -1,14 +1,10 @@ "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 tslib_1 = require("tslib"); 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); + tslib_1.__extends(TypeScriptSemanticGrammar, _super); function TypeScriptSemanticGrammar(registry) { var _this = _super.call(this, registry, { name: "TypeScript", diff --git a/dist/main/atom/views/astView.js b/dist/main/atom/views/astView.js index 7ba81e9ce..01033e3f2 100644 --- a/dist/main/atom/views/astView.js +++ b/dist/main/atom/views/astView.js @@ -1,9 +1,5 @@ "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 tslib_1 = require("tslib"); var sp = require("atom-space-pen-views"); var atomUtils = require("../atomUtils"); var parent = require("../../../worker/parent"); @@ -11,7 +7,7 @@ var d3 = require("d3"); exports.astURI = "ts-ast:"; exports.astURIFull = "ts-ast-full:"; var AstView = (function (_super) { - __extends(AstView, _super); + tslib_1.__extends(AstView, _super); function AstView(filePath, text, full) { var _this = _super.call(this) || this; _this.filePath = filePath; diff --git a/dist/main/atom/views/awesomePanelView.js b/dist/main/atom/views/awesomePanelView.js index 93cb04a9c..7b371883a 100644 --- a/dist/main/atom/views/awesomePanelView.js +++ b/dist/main/atom/views/awesomePanelView.js @@ -1,13 +1,9 @@ "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 tslib_1 = require("tslib"); var view = require("./view"); var $ = view.$; var AwesomePanelView = (function (_super) { - __extends(AwesomePanelView, _super); + tslib_1.__extends(AwesomePanelView, _super); function AwesomePanelView() { return _super.apply(this, arguments) || this; } diff --git a/dist/main/atom/views/contextView.js b/dist/main/atom/views/contextView.js index 65bd020fe..1e443d7ac 100644 --- a/dist/main/atom/views/contextView.js +++ b/dist/main/atom/views/contextView.js @@ -1,9 +1,5 @@ "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 tslib_1 = require("tslib"); var sp = require("atom-space-pen-views"); var mainPanelView = require("./mainPanelView"); var semanticView = require("./semanticView"); @@ -16,7 +12,7 @@ var titles = { }; var items = Object.keys(titles).map(function (item) { return { title: titles[item] }; }); var ContextView = (function (_super) { - __extends(ContextView, _super); + tslib_1.__extends(ContextView, _super); function ContextView() { var _this = _super.apply(this, arguments) || this; _this.panel = null; diff --git a/dist/main/atom/views/dependencyView.js b/dist/main/atom/views/dependencyView.js index ee5d6c744..97ddd60c0 100644 --- a/dist/main/atom/views/dependencyView.js +++ b/dist/main/atom/views/dependencyView.js @@ -1,9 +1,5 @@ "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 tslib_1 = require("tslib"); var sp = require("atom-space-pen-views"); var atomUtils = require("../atomUtils"); var parent = require("../../../worker/parent"); @@ -13,7 +9,7 @@ var fsUtil_1 = require("../../utils/fsUtil"); var os = require("os"); exports.dependencyURI = "ts-dependency:"; var DependencyView = (function (_super) { - __extends(DependencyView, _super); + tslib_1.__extends(DependencyView, _super); function DependencyView(filePath) { var _this = _super.call(this) || this; _this.filePath = filePath; diff --git a/dist/main/atom/views/documentationView.js b/dist/main/atom/views/documentationView.js index 221fcd27a..2242d9a9c 100644 --- a/dist/main/atom/views/documentationView.js +++ b/dist/main/atom/views/documentationView.js @@ -1,13 +1,9 @@ "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 tslib_1 = require("tslib"); var view = require("./view"); var $ = view.$; var DocumentationView = (function (_super) { - __extends(DocumentationView, _super); + tslib_1.__extends(DocumentationView, _super); function DocumentationView() { var _this = _super.apply(this, arguments) || this; _this.shown = false; diff --git a/dist/main/atom/views/fileSymbolsView.js b/dist/main/atom/views/fileSymbolsView.js index ceee0f7e7..ffc7856f4 100644 --- a/dist/main/atom/views/fileSymbolsView.js +++ b/dist/main/atom/views/fileSymbolsView.js @@ -1,13 +1,9 @@ "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 tslib_1 = require("tslib"); var sp = require("atom-space-pen-views"); var atomUtils = require("../atomUtils"); var FileSymbolsView = (function (_super) { - __extends(FileSymbolsView, _super); + tslib_1.__extends(FileSymbolsView, _super); function FileSymbolsView() { var _this = _super.apply(this, arguments) || this; _this.panel = null; diff --git a/dist/main/atom/views/lineMessageView.js b/dist/main/atom/views/lineMessageView.js index e7d373ebb..1c6bbe1e3 100644 --- a/dist/main/atom/views/lineMessageView.js +++ b/dist/main/atom/views/lineMessageView.js @@ -1,13 +1,9 @@ "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 tslib_1 = require("tslib"); var view = require("./view"); var $ = view.$; var LineMessageView = (function (_super) { - __extends(LineMessageView, _super); + tslib_1.__extends(LineMessageView, _super); function LineMessageView() { return _super.apply(this, arguments) || this; } diff --git a/dist/main/atom/views/mainPanelView.js b/dist/main/atom/views/mainPanelView.js index a68b017e8..9c51994ad 100644 --- a/dist/main/atom/views/mainPanelView.js +++ b/dist/main/atom/views/mainPanelView.js @@ -1,9 +1,5 @@ "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 tslib_1 = require("tslib"); var view = require("./view"); var $ = view.$; var lineMessageView = require("./lineMessageView"); @@ -16,7 +12,7 @@ var panelHeaders = { }; var gotoHistory = require("../gotoHistory"); var MainPanelView = (function (_super) { - __extends(MainPanelView, _super); + tslib_1.__extends(MainPanelView, _super); function MainPanelView() { var _this = _super.apply(this, arguments) || this; _this.pendingRequests = []; diff --git a/dist/main/atom/views/plainMessageView.js b/dist/main/atom/views/plainMessageView.js index 18bc8eff6..e036b6f30 100644 --- a/dist/main/atom/views/plainMessageView.js +++ b/dist/main/atom/views/plainMessageView.js @@ -1,13 +1,9 @@ "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 tslib_1 = require("tslib"); var view = require("./view"); var $ = view.$; var PlainMessageView = (function (_super) { - __extends(PlainMessageView, _super); + tslib_1.__extends(PlainMessageView, _super); function PlainMessageView() { return _super.apply(this, arguments) || this; } diff --git a/dist/main/atom/views/projectSymbolsView.js b/dist/main/atom/views/projectSymbolsView.js index c97754181..06732f14a 100644 --- a/dist/main/atom/views/projectSymbolsView.js +++ b/dist/main/atom/views/projectSymbolsView.js @@ -1,13 +1,9 @@ "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 tslib_1 = require("tslib"); var sp = require("atom-space-pen-views"); var atomUtils = require("../atomUtils"); var ProjectSymbolsView = (function (_super) { - __extends(ProjectSymbolsView, _super); + tslib_1.__extends(ProjectSymbolsView, _super); function ProjectSymbolsView() { var _this = _super.apply(this, arguments) || this; _this.panel = null; diff --git a/dist/main/atom/views/rView.js b/dist/main/atom/views/rView.js index b1b34d01f..4150fc453 100644 --- a/dist/main/atom/views/rView.js +++ b/dist/main/atom/views/rView.js @@ -1,14 +1,10 @@ "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 tslib_1 = require("tslib"); var atomUtils_1 = require("../atomUtils"); var sp = require("atom-space-pen-views"); var React = require("react"); var MyComponent = (function (_super) { - __extends(MyComponent, _super); + tslib_1.__extends(MyComponent, _super); function MyComponent(props) { var _this = _super.call(this, props) || this; _this.state = { count: 0 }; @@ -32,7 +28,7 @@ var MyComponent = (function (_super) { }(React.Component)); MyComponent.defaultProps = { count: 0 }; var RView = (function (_super) { - __extends(RView, _super); + tslib_1.__extends(RView, _super); function RView(config) { var _this = _super.call(this) || this; _this.config = config; diff --git a/dist/main/atom/views/renameView.js b/dist/main/atom/views/renameView.js index 06b4367ef..b868f8392 100644 --- a/dist/main/atom/views/renameView.js +++ b/dist/main/atom/views/renameView.js @@ -1,14 +1,10 @@ "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 tslib_1 = require("tslib"); var view = require("./view"); var $ = view.$; var html = require('../../../../views/renameView.html'); var RenameView = (function (_super) { - __extends(RenameView, _super); + tslib_1.__extends(RenameView, _super); function RenameView() { var _this = _super.apply(this, arguments) || this; _this.editorAtRenameStart = null; diff --git a/dist/main/atom/views/semanticView.js b/dist/main/atom/views/semanticView.js index 24dffb763..a9561bde5 100644 --- a/dist/main/atom/views/semanticView.js +++ b/dist/main/atom/views/semanticView.js @@ -1,9 +1,5 @@ "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 tslib_1 = require("tslib"); var atomConfig = require("../atomConfig"); var atomUtils = require("../atomUtils"); var sp = require("atom-space-pen-views"); @@ -17,7 +13,7 @@ var rts; rts.indent = indent; })(rts || (rts = {})); var MyComponent = (function (_super) { - __extends(MyComponent, _super); + tslib_1.__extends(MyComponent, _super); function MyComponent(props) { var _this = _super.call(this, props) || this; _this.whileRendering = { @@ -102,7 +98,7 @@ var MyComponent = (function (_super) { return MyComponent; }(React.Component)); var SemanticView = (function (_super) { - __extends(SemanticView, _super); + tslib_1.__extends(SemanticView, _super); function SemanticView(config) { var _this = _super.call(this, config) || this; _this.config = config; diff --git a/dist/main/atom/views/simpleOverlaySelectionView.js b/dist/main/atom/views/simpleOverlaySelectionView.js index 87c4ffef4..d356d7348 100644 --- a/dist/main/atom/views/simpleOverlaySelectionView.js +++ b/dist/main/atom/views/simpleOverlaySelectionView.js @@ -1,9 +1,5 @@ "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 tslib_1 = require("tslib"); var singleton; function default_1(options, editor) { if (!singleton) @@ -20,7 +16,7 @@ Object.defineProperty(exports, "__esModule", { value: true }); exports.default = default_1; var sp = require("atom-space-pen-views"); var SimpleOverlaySelectListView = (function (_super) { - __extends(SimpleOverlaySelectListView, _super); + tslib_1.__extends(SimpleOverlaySelectListView, _super); function SimpleOverlaySelectListView(options, editor) { var _this = _super.call(this) || this; _this.options = options; diff --git a/dist/main/atom/views/simpleSelectionView.js b/dist/main/atom/views/simpleSelectionView.js index a05fd18df..3e5e436aa 100644 --- a/dist/main/atom/views/simpleSelectionView.js +++ b/dist/main/atom/views/simpleSelectionView.js @@ -1,9 +1,5 @@ "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 tslib_1 = require("tslib"); var singleton; function simpleSelectionView(options) { if (!singleton) @@ -19,7 +15,7 @@ exports.simpleSelectionView = simpleSelectionView; var sp = require("atom-space-pen-views"); var $ = sp.$; var SimpleSelectListView = (function (_super) { - __extends(SimpleSelectListView, _super); + tslib_1.__extends(SimpleSelectListView, _super); function SimpleSelectListView(options) { var _this = _super.call(this) || this; _this.options = options; diff --git a/dist/main/atom/views/tooltipView.js b/dist/main/atom/views/tooltipView.js index dd297a53d..153c2335f 100644 --- a/dist/main/atom/views/tooltipView.js +++ b/dist/main/atom/views/tooltipView.js @@ -1,13 +1,9 @@ "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 tslib_1 = require("tslib"); var view = require("./view"); var $ = view.$; var TooltipView = (function (_super) { - __extends(TooltipView, _super); + tslib_1.__extends(TooltipView, _super); function TooltipView(rect) { var _this = _super.call(this, rect) || this; _this.rect = rect; diff --git a/dist/main/atom/views/view.js b/dist/main/atom/views/view.js index b712139cb..38eb597f0 100644 --- a/dist/main/atom/views/view.js +++ b/dist/main/atom/views/view.js @@ -1,12 +1,8 @@ "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 tslib_1 = require("tslib"); var sp = require("atom-space-pen-views"); var View = (function (_super) { - __extends(View, _super); + tslib_1.__extends(View, _super); function View(options) { var _this = _super.call(this) || this; _this.options = options; @@ -29,7 +25,7 @@ var View = (function (_super) { exports.View = View; exports.$ = sp.$; var ScrollView = (function (_super) { - __extends(ScrollView, _super); + tslib_1.__extends(ScrollView, _super); function ScrollView(options) { var _this = _super.call(this) || this; _this.options = options; diff --git a/dist/main/atomts.js b/dist/main/atomts.js index d33127b5e..0f12da665 100644 --- a/dist/main/atomts.js +++ b/dist/main/atomts.js @@ -1,39 +1,5 @@ "use strict"; -var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) { - return new (P || (P = Promise))(function (resolve, reject) { - function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } } - function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } } - function step(result) { result.done ? resolve(result.value) : new P(function (resolve) { resolve(result.value); }).then(fulfilled, rejected); } - step((generator = generator.apply(thisArg, _arguments)).next()); - }); -}; -var __generator = (this && this.__generator) || function (thisArg, body) { - var _ = { label: 0, sent: function() { if (t[0] & 1) throw t[1]; return t[1]; }, trys: [], ops: [] }, f, y, t; - return { next: verb(0), "throw": verb(1), "return": verb(2) }; - function verb(n) { return function (v) { return step([n, v]); }; } - function step(op) { - if (f) throw new TypeError("Generator is already executing."); - while (_) try { - if (f = 1, y && (t = y[op[0] & 2 ? "return" : op[0] ? "throw" : "next"]) && !(t = t.call(y, op[1])).done) return t; - if (y = 0, t) op = [0, t.value]; - switch (op[0]) { - case 0: case 1: t = op; break; - case 4: _.label++; return { value: op[1], done: false }; - case 5: _.label++; y = op[1]; op = [0]; continue; - case 7: op = _.ops.pop(); _.trys.pop(); continue; - default: - if (!(t = _.trys, t = t.length > 0 && t[t.length - 1]) && (op[0] === 6 || op[0] === 2)) { _ = 0; continue; } - if (op[0] === 3 && (!t || (op[1] > t[0] && op[1] < t[3]))) { _.label = op[1]; break; } - if (op[0] === 6 && _.label < t[1]) { _.label = t[1]; t = op; break; } - if (t && _.label < t[2]) { _.label = t[2]; _.ops.push(op); break; } - if (t[2]) _.ops.pop(); - _.trys.pop(); continue; - } - op = body.call(thisArg, _); - } catch (e) { op = [6, e]; y = 0; } finally { f = t = 0; } - if (op[0] & 5) throw op[1]; return { value: op[0] ? op[1] : void 0, done: true }; - } -}; +var tslib_1 = require("tslib"); var atomConfig = require("./atom/atomConfig"); var makeTypeScriptGlobal_1 = require("../typescript/makeTypeScriptGlobal"); makeTypeScriptGlobal_1.makeTsGlobal(atomConfig.typescriptServices); @@ -95,9 +61,9 @@ function readyToActivate() { } }); editorWatch = atom.workspace.observeTextEditors(function (editor) { - return __awaiter(this, void 0, void 0, function () { + return tslib_1.__awaiter(this, void 0, void 0, function () { var filePath, client, editorView, ext, unsubSyntax_1, unsubSemantic_1, isTst, onDisk, changeObserver, buffer, fasterChangeObserver, saveObserver, destroyObserver; - return __generator(this, function (_a) { + return tslib_1.__generator(this, function (_a) { switch (_a.label) { case 0: filePath = editor.getPath(); diff --git a/dist/worker/lib/workerLib.js b/dist/worker/lib/workerLib.js index 351d1bc05..ee86259ff 100644 --- a/dist/worker/lib/workerLib.js +++ b/dist/worker/lib/workerLib.js @@ -1,9 +1,5 @@ "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 tslib_1 = require("tslib"); var childprocess = require("child_process"); var exec = childprocess.exec; var spawn = childprocess.spawn; @@ -146,7 +142,7 @@ var RequesterResponder = (function () { return RequesterResponder; }()); var Parent = (function (_super) { - __extends(Parent, _super); + tslib_1.__extends(Parent, _super); function Parent() { var _this = _super.apply(this, arguments) || this; _this.node = process.execPath; @@ -221,7 +217,7 @@ var Parent = (function (_super) { }(RequesterResponder)); exports.Parent = Parent; var Child = (function (_super) { - __extends(Child, _super); + tslib_1.__extends(Child, _super); function Child() { var _this = _super.call(this) || this; _this.getProcess = function () { return process; }; diff --git a/lib/main/atom/autoCompleteProvider.ts b/lib/main/atom/autoCompleteProvider.ts index c78b690c7..047ad7323 100644 --- a/lib/main/atom/autoCompleteProvider.ts +++ b/lib/main/atom/autoCompleteProvider.ts @@ -91,109 +91,104 @@ export var provider: autocompleteplus.Provider = { inclusionPriority: 3, suggestionPriority: 3, excludeLowerPriority: false, - getSuggestions: (options: autocompleteplus.RequestOptions): Promise=> { + getSuggestions: async function (options: autocompleteplus.RequestOptions): Promise { - var filePath = options.editor.getPath(); + const filePath = options.editor.getPath() // We refuse to work on files that are not on disk. - if (!filePath) return Promise.resolve([]); - if (!fs.existsSync(filePath)) return Promise.resolve([]); - - var {isReference, isRequire, isImport} = getModuleAutocompleteType(options.scopeDescriptor.scopes) - - // For file path completions - if (isReference || isRequire || isImport) { - return parent.getRelativePathsInProject({ filePath, prefix: options.prefix, includeExternalModules: isReference }) - .then((resp) => { - - var range = options.editor.bufferRangeForScopeAtCursor(".string.quoted") - var cursor = options.editor.getCursorBufferPosition() - - // 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 [] - } - - var content = options.editor.getTextInBufferRange(range).replace(/^['"]|['"]$/g, "") - - return resp.files.map(file => { - var relativePath = file.relativePath; - - /** Optionally customize this in future */ - var suggestionText = relativePath; - - var suggestion: autocompleteplus.Suggestion = { - text: suggestionText, - replacementPrefix: content, - rightLabelHTML: '' + file.name + '', - type: 'import' - }; - - return suggestion; - }); - }); - } - else { + if (!filePath || !fs.existsSync(filePath)) + return []; + + const client = await parent.clients.get(filePath) + + // var {isReference, isRequire, isImport} = getModuleAutocompleteType(options.scopeDescriptor.scopes) + // + // // For file path completions + // if (isReference || isRequire || isImport) { + // return parent.getRelativePathsInProject({ filePath, prefix: options.prefix, includeExternalModules: isReference }) + // .then((resp) => { + // + // var range = options.editor.bufferRangeForScopeAtCursor(".string.quoted") + // var cursor = options.editor.getCursorBufferPosition() + // + // // 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 [] + // } + // + // var content = options.editor.getTextInBufferRange(range).replace(/^['"]|['"]$/g, "") + // + // return resp.files.map(file => { + // var relativePath = file.relativePath; + // + // /** Optionally customize this in future */ + // var suggestionText = relativePath; + // + // var suggestion: autocompleteplus.Suggestion = { + // text: suggestionText, + // replacementPrefix: content, + // rightLabelHTML: '' + file.name + '', + // type: 'import' + // }; + // + // 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 (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([]); - } + if (prefix === '' || prefix === ';' || prefix === '{') { + return Promise.resolve([]); } + } - return parent.clients.get(filePath).then(client => { - return client.executeCompletions({ - file: filePath, - prefix: options.prefix, - line: options.bufferPosition.row+1, - offset: options.bufferPosition.column+1 - }).then(resp => { - console.log("prefix", options.prefix) - - var completionList = resp.body; - var suggestions: autocompleteplus.Suggestion[] = completionList.map(c => { - - // 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: prefix.trim(), - rightLabel: c.name, - leftLabel: c.kind, - type: atomUtils.kindToType(c.kind), - description: null, - }; - // } - }); - - return suggestions; + return client.executeCompletions({ + file: filePath, + prefix: options.prefix, + line: options.bufferPosition.row+1, + offset: options.bufferPosition.column+1 + }).then(resp => { + console.log("prefix", options.prefix) + return resp.body.map(c => { + + // 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: prefix === "." ? "" : prefix.trim(), + rightLabel: c.name, + leftLabel: c.kind, + type: atomUtils.kindToType(c.kind), + description: null, + }; + // } }); - }) - } + }); }, } diff --git a/lib/tsconfig.json b/lib/tsconfig.json index 61b7546b7..fac28fae8 100644 --- a/lib/tsconfig.json +++ b/lib/tsconfig.json @@ -5,6 +5,7 @@ "declaration": false, "lib": ["es6", "dom"], "noImplicitAny": false, + "importHelpers": true, "removeComments": true, "noLib": false, "preserveConstEnums": true, diff --git a/package.json b/package.json index 6e8284418..4f145eafa 100644 --- a/package.json +++ b/package.json @@ -75,6 +75,7 @@ "resolve": "1.1.7", "season": "^5.1.4", "tsconfig": "^2.2.0", + "tslib": "1.2.0", "typescript": "2.2.0-dev.20161130", "xtend": "^4.0.0" }, From f16a8ba60246e94f5846715c59af21e369052dee Mon Sep 17 00:00:00 2001 From: Guntars Asmanis-Graham Date: Wed, 30 Nov 2016 20:58:54 -0500 Subject: [PATCH 13/70] Remove some more codes, wait until grammar is loaded to start the plugin --- dist/main/atom/atomUtils.js | 14 --- dist/main/atom/commands/commands.js | 96 +-------------- dist/main/atomts.js | 15 ++- keymaps/atom-typescript.cson | 2 - lib/main/atom/atomUtils.ts | 17 +-- lib/main/atom/commands/commands.ts | 173 +--------------------------- lib/main/atomts.ts | 40 +++---- package.json | 10 +- 8 files changed, 33 insertions(+), 334 deletions(-) diff --git a/dist/main/atom/atomUtils.js b/dist/main/atom/atomUtils.js index 633e8e027..a45ee829b 100644 --- a/dist/main/atom/atomUtils.js +++ b/dist/main/atom/atomUtils.js @@ -246,17 +246,3 @@ 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; diff --git a/dist/main/atom/commands/commands.js b/dist/main/atom/commands/commands.js index a006ec803..eb4e724e4 100644 --- a/dist/main/atom/commands/commands.js +++ b/dist/main/atom/commands/commands.js @@ -18,7 +18,6 @@ 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"); @@ -33,32 +32,6 @@ function registerCommands() { 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; @@ -158,9 +131,6 @@ function registerCommands() { 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; @@ -168,38 +138,7 @@ function registerCommands() { }); 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 { + if (true) { parent.getRenameInfo(atomUtils.getFilePathPosition()).then(function (res) { if (!res.canRename) { atom.notifications.addInfo('AtomTS: Rename not available at cursor location'); @@ -333,7 +272,7 @@ function registerCommands() { 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) { + atom.commands.add('atom-text-editor', 'symbols-view:toggle-project-symbols', function (e) { var editor = atom.workspace.getActiveTextEditor(); if (!editor) return false; @@ -384,30 +323,6 @@ function registerCommands() { 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', @@ -424,12 +339,5 @@ function registerCommands() { 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/atomts.js b/dist/main/atomts.js index 0f12da665..0876d95bb 100644 --- a/dist/main/atomts.js +++ b/dist/main/atomts.js @@ -1,5 +1,7 @@ "use strict"; var tslib_1 = require("tslib"); +console.log("be initializing them package"); +var start = process.hrtime(); var atomConfig = require("./atom/atomConfig"); var makeTypeScriptGlobal_1 = require("../typescript/makeTypeScriptGlobal"); makeTypeScriptGlobal_1.makeTsGlobal(atomConfig.typescriptServices); @@ -176,7 +178,13 @@ function updatePanelConfig(filePath) { }); } function activate(state) { - require('atom-package-deps').install('atom-typescript').then(readyToActivate); + console.log("activating them package", state); + atom.workspace.observeTextEditors(function (editor) { + console.log("opened editor", editor); + editor.observeGrammar(function (grammar) { + console.log("observed grammar", grammar); + }); + }); } exports.activate = activate; function deactivate() { @@ -205,12 +213,9 @@ function provideLinter() { return linter.provider; } exports.provideLinter = provideLinter; -function consumeSnippets(snippetsManager) { - atomUtils._setSnippetsManager(snippetsManager); -} -exports.consumeSnippets = consumeSnippets; var hyperclickProvider = require("../hyperclickProvider"); function getHyperclickProvider() { return hyperclickProvider; } exports.getHyperclickProvider = getHyperclickProvider; +console.log("init took", process.hrtime(start)); diff --git a/keymaps/atom-typescript.cson b/keymaps/atom-typescript.cson index 8e8021dcd..14fe2b473 100644 --- a/keymaps/atom-typescript.cson +++ b/keymaps/atom-typescript.cson @@ -8,8 +8,6 @@ 'alt-enter': 'typescript:quick-fix' 'ctrl-M': 'typescript:output-toggle' 'cmd-M': 'typescript:output-toggle' -# Debuging - 'f9': 'typescript:toggle-breakpoint' # Stronger bindings 'atom-workspace': diff --git a/lib/main/atom/atomUtils.ts b/lib/main/atom/atomUtils.ts index 2534b157a..b691a989b 100644 --- a/lib/main/atom/atomUtils.ts +++ b/lib/main/atom/atomUtils.ts @@ -295,19 +295,4 @@ export function openFile(filePath: string, position: { line?: number; col?: numb config.initialColumn = position.col; } 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?'); - } -} +} \ No newline at end of file diff --git a/lib/main/atom/commands/commands.ts b/lib/main/atom/commands/commands.ts index 7b37e7e31..975ac3656 100644 --- a/lib/main/atom/commands/commands.ts +++ b/lib/main/atom/commands/commands.ts @@ -39,36 +39,6 @@ export function registerCommands() { 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; @@ -191,37 +161,6 @@ export function registerCommands() { 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; @@ -231,45 +170,9 @@ export function registerCommands() { 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 { + if (true) { parent.getRenameInfo(atomUtils.getFilePathPosition()).then((res) => { if (!res.canRename) { atom.notifications.addInfo('AtomTS: Rename not available at cursor location'); @@ -430,7 +333,7 @@ export function registerCommands() { 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', + atom.commands.add('atom-text-editor', 'symbols-view:toggle-project-symbols', (e) => { var editor = atom.workspace.getActiveTextEditor(); if (!editor) return false; @@ -488,38 +391,6 @@ export function registerCommands() { } }); - 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', @@ -538,44 +409,4 @@ export function registerCommands() { 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/atomts.ts b/lib/main/atomts.ts index 6aab8a5da..bb5c24c17 100644 --- a/lib/main/atomts.ts +++ b/lib/main/atomts.ts @@ -1,3 +1,6 @@ +console.log("be initializing them package") +const start = process.hrtime() + import atomConfig = require('./atom/atomConfig'); import {makeTsGlobal} from "../typescript/makeTypeScriptGlobal"; makeTsGlobal(atomConfig.typescriptServices); @@ -339,7 +342,17 @@ function updatePanelConfig(filePath: string) { } export function activate(state: PackageState) { - require('atom-package-deps').install('atom-typescript').then(readyToActivate) + console.log("activating them package", state) + + atom.workspace.observeTextEditors(function(editor){ + console.log("opened editor", editor) + + editor.observeGrammar(function(grammar) { + console.log("observed grammar", grammar) + }) + }) + + // require('atom-package-deps').install('atom-typescript').then(readyToActivate) } export function deactivate() { @@ -368,30 +381,9 @@ export function provideLinter() { return linter.provider; } -export function consumeSnippets(snippetsManager) { - atomUtils._setSnippetsManager(snippetsManager); -} - -// 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; -// } - import * as hyperclickProvider from "../hyperclickProvider"; export function getHyperclickProvider() { return hyperclickProvider; } + +console.log("init took", process.hrtime(start)) \ No newline at end of file diff --git a/package.json b/package.json index 4f145eafa..4eac55e71 100644 --- a/package.json +++ b/package.json @@ -5,8 +5,9 @@ "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", @@ -33,13 +34,6 @@ } } }, - "consumedServices": { - "snippets": { - "versions": { - "0.1.0": "consumeSnippets" - } - } - }, "homepage": "http://atom.io/packages/atom-typescript", "repository": { "type": "git", From 35cecd569566ca7fe89990a47cba627824b45078 Mon Sep 17 00:00:00 2001 From: Guntars Asmanis-Graham Date: Wed, 30 Nov 2016 21:54:51 -0500 Subject: [PATCH 14/70] Delete more things --- README.md | 9 +- dist/client/clientMap.js | 1 - dist/client/findTSServer.js | 87 -- dist/linter.js | 15 - dist/main/atom/autoCompleteProvider.js | 6 +- dist/main/atom/commands/commands.js | 45 - dist/main/atom/commands/moveFilesHandling.js | 4 - dist/main/atom/commands/outputFileCommands.js | 58 -- dist/main/atom/commands/reactCommand.js | 14 - dist/main/atom/commands/reactCommands.js | 16 - dist/main/atom/views/contextView.js | 5 - dist/main/atom/views/fileSemanticView.js | 32 - dist/main/atom/views/rView.js | 62 -- dist/main/atomts.js | 33 +- dist/main/bin/atbuild | 2 - dist/main/bin/atbuild.js | 33 - dist/main/lang/modules/building.js | 163 ---- dist/main/lang/projectService.js | 145 +--- dist/worker/parent.js | 6 - docs/faq.md | 16 - lib/globals.ts | 5 - lib/linter.ts | 69 +- lib/main/atom/autoCompleteProvider.ts | 16 +- lib/main/atom/commands/commands.ts | 54 -- lib/main/atom/commands/moveFilesHandling.ts | 12 - lib/main/atom/commands/outputFileCommands.ts | 64 -- lib/main/atom/commands/reactCommands.ts | 21 - lib/main/atom/views/contextView.ts | 5 - lib/main/atom/views/rView.tsx | 74 -- lib/main/atom/views/semanticView.tsx | 188 ----- lib/main/atomts.ts | 65 +- lib/main/bin/atbuild.ts | 44 - lib/main/lang/modules/building.ts | 205 ----- lib/main/lang/projectService.ts | 177 +--- lib/main/tsconfig/tsconfig.ts | 1 - lib/tsd.json | 9 - lib/typings/react/react-jsx.d.ts | 147 ---- lib/typings/react/react.d.ts | 789 ------------------ lib/typings/tsd.d.ts | 3 - lib/worker/parent.ts | 6 - package.json | 20 +- 41 files changed, 74 insertions(+), 2652 deletions(-) delete mode 100644 dist/client/clientMap.js delete mode 100644 dist/client/findTSServer.js delete mode 100644 dist/main/atom/commands/moveFilesHandling.js delete mode 100644 dist/main/atom/commands/outputFileCommands.js delete mode 100644 dist/main/atom/commands/reactCommand.js delete mode 100644 dist/main/atom/commands/reactCommands.js delete mode 100644 dist/main/atom/views/fileSemanticView.js delete mode 100644 dist/main/atom/views/rView.js delete mode 100644 dist/main/bin/atbuild delete mode 100644 dist/main/bin/atbuild.js delete mode 100644 lib/main/atom/commands/moveFilesHandling.ts delete mode 100644 lib/main/atom/commands/outputFileCommands.ts delete mode 100644 lib/main/atom/commands/reactCommands.ts delete mode 100644 lib/main/atom/views/rView.tsx delete mode 100644 lib/main/atom/views/semanticView.tsx delete mode 100644 lib/main/bin/atbuild.ts delete mode 100644 lib/typings/react/react-jsx.d.ts delete mode 100644 lib/typings/react/react.d.ts diff --git a/README.md b/README.md index c72064872..9b0100f68 100644 --- a/README.md +++ b/README.md @@ -15,9 +15,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,7 +30,6 @@ 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 @@ -94,8 +93,6 @@ Shortcut: `F6`. If there are any errors they are shown as well. ## NPM Module Support We have a sample NPM module : https://github.com/basarat/ts-npm-module (trick : in tsconfig have `"declaration" : true` an in package.json have a `typings` field pointing to the `main` file) and its usage is demoed in https://github.com/basarat/ts-npm-module-consume. -## React Support - ### Configuration tips Covered here : http://basarat.gitbooks.io/typescript/content/docs/jsx/tsx.html diff --git a/dist/client/clientMap.js b/dist/client/clientMap.js deleted file mode 100644 index 3918c74e4..000000000 --- a/dist/client/clientMap.js +++ /dev/null @@ -1 +0,0 @@ -"use strict"; diff --git a/dist/client/findTSServer.js b/dist/client/findTSServer.js deleted file mode 100644 index 4c98f35f0..000000000 --- a/dist/client/findTSServer.js +++ /dev/null @@ -1,87 +0,0 @@ -"use strict"; -var fs = require("fs"); -var path = require("path"); -var resolve = require("resolve"); -function findTSServer(basedir) { - var tsPath = resolve.sync("typescript/package.json", { basedir: basedir }); - var tsServerPath = path.resolve(path.dirname(tsPath), "bin", "tsserver"); - fs.statSync(tsServerPath); - return tsServerPath; -} -exports.findTSServer = findTSServer; -function findTypescriptServers(root) { - var results = []; - if (!path.isAbsolute(root)) { - throw new Error("Argument should be an absolute path"); - } - return new Promise(function (resolve) { - walk(root, function () { - resolve(results); - }); - }); - function walk(dir, done) { - fs.readdir(dir, function (err, files) { - if (err || files.length === 0) - return done(); - var doneEntry = after(files.length, function () { - done(); - }); - for (var _i = 0, files_1 = files; _i < files_1.length; _i++) { - var entry = files_1[_i]; - if (entry === "node_modules") { - fs.stat(path.join(dir, entry, "typescript"), function (err) { - if (err) { - doneEntry(); - } - else { - getServerInfo(dir, function (err, info) { - if (info) - results.push(info); - doneEntry(); - }); - } - }); - } - else if (entry === ".git" || entry === "bower_components") { - doneEntry(); - } - else { - walk(path.join(dir, entry), doneEntry); - } - } - }); - } -} -exports.findTypescriptServers = findTypescriptServers; -function getServerInfo(prefix, callback) { - var tsDir = path.join(prefix, "node_modules", "typescript"); - fs.readFile(path.join(tsDir, "package.json"), "utf8", function (err, pkg) { - if (err) - return callback(err, null); - try { - var version_1 = JSON.parse(pkg).version; - var tsServerPath_1 = path.join(tsDir, "bin", "tsserver"); - fs.stat(tsServerPath_1, function (err, stat) { - if (err) - return callback(err, null); - callback(null, { - binPath: tsServerPath_1, - prefix: prefix, - version: version_1 - }); - }); - } - catch (error) { - callback(error, null); - } - }); -} -function after(count, callback) { - var called = 0; - return function () { - called++; - if (called >= count) { - callback.apply(this, arguments); - } - }; -} diff --git a/dist/linter.js b/dist/linter.js index ebac46336..3918c74e4 100644 --- a/dist/linter.js +++ b/dist/linter.js @@ -1,16 +1 @@ "use strict"; -var fs = require("fs"); -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 Promise.resolve([]); - } -}; diff --git a/dist/main/atom/autoCompleteProvider.js b/dist/main/atom/autoCompleteProvider.js index dfe27f2ba..c64cc35aa 100644 --- a/dist/main/atom/autoCompleteProvider.js +++ b/dist/main/atom/autoCompleteProvider.js @@ -1,10 +1,8 @@ "use strict"; var tslib_1 = require("tslib"); -var parent = require("../../worker/parent"); -var fs = require("fs"); var atomUtils = require("./atomUtils"); -var fuzzaldrin = require('fuzzaldrin'); -var CSON = require("season"); +var fs = require("fs"); +var parent = require("../../worker/parent"); var explicitlyTriggered = false; function triggerAutocompletePlus() { atom.commands.dispatch(atom.views.getView(atom.workspace.getActiveTextEditor()), 'autocomplete-plus:activate'); diff --git a/dist/main/atom/commands/commands.js b/dist/main/atom/commands/commands.js index eb4e724e4..86b1fcf60 100644 --- a/dist/main/atom/commands/commands.js +++ b/dist/main/atom/commands/commands.js @@ -3,7 +3,6 @@ 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"); @@ -18,19 +17,10 @@ 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 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")); function registerCommands() { - outputFileCommands.register(); - moveFilesHandling_1.registerRenameHandling(); - reactCommands_1.registerReactCommands(); json2dtsCommands_1.registerJson2dtsCommands(); atom.commands.add('atom-text-editor', 'typescript:format-code', function (e) { if (!atomUtils.commandForTypeScript(e)) @@ -57,25 +47,6 @@ function registerCommands() { }); } }); - 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; @@ -131,11 +102,6 @@ function registerCommands() { atom.commands.add('atom-text-editor', 'typescript:autocomplete', function (e) { autoCompleteProvider.triggerAutocompletePlus(); }); - 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(); if (true) { @@ -323,17 +289,6 @@ function registerCommands() { return new dependencyView_1.DependencyView(data.filePath); } }); - 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; 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/views/contextView.js b/dist/main/atom/views/contextView.js index 1e443d7ac..ff330717e 100644 --- a/dist/main/atom/views/contextView.js +++ b/dist/main/atom/views/contextView.js @@ -2,13 +2,11 @@ var tslib_1 = require("tslib"); 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) { @@ -42,9 +40,6 @@ var ContextView = (function (_super) { if (item.title == titles.tabReferences) { mainPanelView.panelView.referencesPanelSelected(); } - if (item.title == titles.fileSemantics) { - semanticView.toggle(); - } this.hide(); }; ContextView.prototype.getFilterKey = function () { return 'title'; }; 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/rView.js b/dist/main/atom/views/rView.js deleted file mode 100644 index 4150fc453..000000000 --- a/dist/main/atom/views/rView.js +++ /dev/null @@ -1,62 +0,0 @@ -"use strict"; -var tslib_1 = require("tslib"); -var atomUtils_1 = require("../atomUtils"); -var sp = require("atom-space-pen-views"); -var React = require("react"); -var MyComponent = (function (_super) { - tslib_1.__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) { - tslib_1.__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/atomts.js b/dist/main/atomts.js index 0876d95bb..75b54c712 100644 --- a/dist/main/atomts.js +++ b/dist/main/atomts.js @@ -1,12 +1,14 @@ "use strict"; var tslib_1 = require("tslib"); console.log("be initializing them package"); +console.profile("atomts init"); var start = process.hrtime(); 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 _ = require("lodash"); var mainPanelView_1 = require("./atom/views/mainPanelView"); var autoCompleteProvider = require("./atom/autoCompleteProvider"); var tooltipManager = require("./atom/tooltipManager"); @@ -18,7 +20,6 @@ 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; @@ -28,29 +29,23 @@ var autoCompleteWatch; var parent = require("../worker/parent"); exports.config = atomConfig.schema; var utils_1 = require("./lang/utils"); +var linter; 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; +var attachViews = _.once(function () { 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(); + attachViews(); updatePanelConfig(filePath); mainPanelView.panelView.updateFileStatus(filePath); mainPanelView.show(); @@ -97,7 +92,7 @@ function readyToActivate() { }); isTst = ext === '.tst'; try { - onlyOnceStuff(); + attachViews(); client.executeOpen({ file: filePath, fileContent: editor.getText() @@ -204,18 +199,22 @@ exports.serialize = serialize; function deserialize() { } exports.deserialize = deserialize; +function consumeLinter(registry) { + console.log("consume this"); + linter = registry.register({ + name: "Typescript" + }); + console.log("got linter", linter); +} +exports.consumeLinter = consumeLinter; function provide() { return [autoCompleteProvider.provider]; } exports.provide = provide; -var linter = require("../linter"); -function provideLinter() { - return linter.provider; -} -exports.provideLinter = provideLinter; var hyperclickProvider = require("../hyperclickProvider"); function getHyperclickProvider() { return hyperclickProvider; } exports.getHyperclickProvider = getHyperclickProvider; +console.profileEnd(); console.log("init took", process.hrtime(start)); diff --git a/dist/main/bin/atbuild b/dist/main/bin/atbuild deleted file mode 100644 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/lang/modules/building.js b/dist/main/lang/modules/building.js index facaaad3e..fef9804b1 100644 --- a/dist/main/lang/modules/building.js +++ b/dist/main/lang/modules/building.js @@ -1,12 +1,7 @@ "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; @@ -21,49 +16,6 @@ function diagnosticToTSError(diagnostic) { }; } 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; @@ -79,121 +31,6 @@ function getRawOutput(proj, filePath) { 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"); } diff --git a/dist/main/lang/projectService.js b/dist/main/lang/projectService.js index bb666d38c..3afded94c 100644 --- a/dist/main/lang/projectService.js +++ b/dist/main/lang/projectService.js @@ -1,11 +1,8 @@ "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"); var fuzzaldrin = require('fuzzaldrin'); -var transformer_1 = require("./transformers/transformer"); var transformer = require("./transformers/transformer"); var tsconfig = require("../tsconfig/tsconfig"); var utils = require("./utils"); @@ -43,61 +40,6 @@ function quickInfo(query) { } } exports.quickInfo = quickInfo; -var 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'); }); - filesToEmit = proj.projectFile.project.compilerOptions.outFile ? [filesToEmit[0]] : filesToEmit; - var totalCount = filesToEmit.length; - var builtCount = 0; - var errorCount = 0; - var outputs = filesToEmit.map(function (filePath) { - var output = building.emitFile(proj, filePath); - builtCount++; - errorCount = errorCount + output.errors.length; - projectCache_1.queryParent.buildUpdate({ - totalCount: totalCount, - builtCount: builtCount, - errorCount: errorCount, - firstError: errorCount && !(errorCount - output.errors.length), - filePath: filePath, - errorsInFile: output.errors - }); - return output; - }); - building.emitDts(proj); - 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) { - if (err) { - console.error('postbuild failed!'); - console.error(proj.projectFile.project.scripts.postbuild); - console.error(stderr); - } - }); - } - 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; }); - return resolve({ - tsFilesWithInvalidEmit: tsFilesWithInvalidEmit, - tsFilesWithValidEmit: tsFilesWithValidEmit, - buildOutput: { - outputs: outputs, - counts: { - inputFiles: proj.projectFile.project.files.length, - outputFiles: utils.selectMany(outputs.map(function (out) { return out.outputFiles; })).length, - errors: errorCount, - emitErrors: outputs.filter(function (out) { return out.emitError; }).length - } - } - }); -} -exports.build = build; function getCompletionsAtPosition(query) { projectCache_1.consistentPath(query); var filePath = query.filePath, position = query.position, prefix = query.prefix; @@ -179,12 +121,6 @@ function getSignatureHelps(query) { return signatureHelpItems.items; } exports.getSignatureHelps = getSignatureHelps; -function emitFile(query) { - projectCache_1.consistentPath(query); - var filePath = transformer.getPseudoFilePath(query.filePath); - return resolve(building.emitFile(projectCache_1.getOrCreateProject(filePath), filePath)); -} -exports.emitFile = emitFile; var formatting = require("./modules/formatting"); function formatDocument(query) { projectCache_1.consistentPath(query); @@ -245,44 +181,6 @@ function getDiagnositcsByFilePath(query) { } return diagnostics; } -function errorsForFile(query) { - projectCache_1.consistentPath(query); - var project; - try { - project = projectCache_1.getOrCreateProject(query.filePath); - } - catch (ex) { - return resolve({ errors: [] }); - } - if (transformer_1.isTransformerFile(query.filePath)) { - var filePath = transformer.getPseudoFilePath(query.filePath); - var errors = getDiagnositcsByFilePath({ filePath: filePath }).map(building.diagnosticToTSError); - errors.forEach(function (error) { - error.filePath = query.filePath; - }); - return resolve({ errors: errors }); - } - else { - var result = void 0; - if (project.includesSourceFile(query.filePath)) { - result = getDiagnositcsByFilePath(query).map(building.diagnosticToTSError); - } - else { - result = notInContextResult(query.filePath); - } - return resolve({ errors: result }); - } -} -exports.errorsForFile = errorsForFile; -function notInContextResult(fileName) { - 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: "" - }]; -} function getRenameInfo(query) { projectCache_1.consistentPath(query); var project = projectCache_1.getOrCreateProject(query.filePath); @@ -577,49 +475,8 @@ function applyQuickFix(query) { return resolve({ refactorings: refactorings }); } exports.applyQuickFix = applyQuickFix; -var building_1 = require("./modules/building"); -function getOutput(query) { - projectCache_1.consistentPath(query); - var project = projectCache_1.getOrCreateProject(query.filePath); - return resolve({ output: building_1.getRawOutput(project, query.filePath) }); -} -exports.getOutput = getOutput; -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]; - if (!jsFile || output.emitSkipped) { - return resolve({}); - } - else { - return resolve({ jsFilePath: jsFile.name }); - } -} -exports.getOutputJs = getOutputJs; -function getOutputJsStatus(query) { - projectCache_1.consistentPath(query); - var project = projectCache_1.getOrCreateProject(query.filePath); - var output = building_1.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(function (x) { return 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 }); - } -} -exports.getOutputJsStatus = getOutputJsStatus; function softReset(query) { + console.log("Resetting.."); projectCache_1.resetCache(query); return resolve({}); } diff --git a/dist/worker/parent.js b/dist/worker/parent.js index 783211096..e783ab632 100644 --- a/dist/worker/parent.js +++ b/dist/worker/parent.js @@ -39,18 +39,15 @@ function catchCommonErrors(func) { } var projectService = require("../main/lang/projectService"); exports.echo = catchCommonErrors(parent.sendToIpc(projectService.echo)); -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)); @@ -64,9 +61,6 @@ 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); diff --git a/docs/faq.md b/docs/faq.md index a1f2964ac..9d22aadec 100644 --- a/docs/faq.md +++ b/docs/faq.md @@ -37,22 +37,6 @@ You can see the date `typescript` dependency was updated in our [`package.json`] ## 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 diff --git a/lib/globals.ts b/lib/globals.ts index 6133df676..dda204e5b 100644 --- a/lib/globals.ts +++ b/lib/globals.ts @@ -38,11 +38,6 @@ declare module 'detect-newline' { 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 { } diff --git a/lib/linter.ts b/lib/linter.ts index a8abc6e01..cba9a290f 100644 --- a/lib/linter.ts +++ b/lib/linter.ts @@ -1,15 +1,14 @@ -// 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 +export interface Linter { + deleteMessages() + sendMessages(messages: LinterMessage[]) + dispose() +} -import fs = require('fs'); -import {Range} from "atom"; +export interface LinterConfig { + name: string +} -interface LinterMessage { +export interface LinterMessage { type: string, // "Error" or "Warning" text?: string, html?: string, @@ -18,50 +17,6 @@ interface LinterMessage { // 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 Promise.resolve([]) - - // // Trigger an error check - // parent.client.executeGetErr({files: [filePath], delay: 100}) - // - // return new Promise((resolve, reject) => { - // - // // Listen for a semanticDiag message for this specific file, unsub and resolve - // const unsub = parent.client.on("semanticDiag", result => { - // if (result.file === filePath) { - // try { - // unsub() - // - // const errors: LinterMessage[] = result.diagnostics.map(diag => { - // return { - // type: "Error", - // filePath, - // text: diag.text, - // range: new Range( - // [diag.start.line-1, diag.start.offset-1], - // [diag.end.line-1, diag.end.offset-1]) - // } - // }) - // - // resolve(errors) - // } catch (error) { - // resolve([]) - // } - // } - // }) - // }) - } -} +export interface LinterRegistry { + register(config: LinterConfig): Linter +} \ No newline at end of file diff --git a/lib/main/atom/autoCompleteProvider.ts b/lib/main/atom/autoCompleteProvider.ts index 047ad7323..d1febdb94 100644 --- a/lib/main/atom/autoCompleteProvider.ts +++ b/lib/main/atom/autoCompleteProvider.ts @@ -1,18 +1,10 @@ -/// // more: https://github.com/atom-community/autocomplete-plus/wiki/Provider-API -///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"); +import atomConfig = require('./atomConfig') +import atomUtils = require('./atomUtils') +import fs = require('fs') +import parent = require('../../worker/parent') declare module autocompleteplus { /** What gets passed into the handler */ diff --git a/lib/main/atom/commands/commands.ts b/lib/main/atom/commands/commands.ts index 975ac3656..2b851d8b5 100644 --- a/lib/main/atom/commands/commands.ts +++ b/lib/main/atom/commands/commands.ts @@ -17,16 +17,11 @@ 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"; @@ -34,9 +29,6 @@ export * from "../components/componentRegistry"; export function registerCommands() { // Stuff I've split out as we have a *lot* of commands - outputFileCommands.register(); - registerRenameHandling(); - registerReactCommands(); registerJson2dtsCommands(); // Setup custom commands NOTE: these need to be added to the keymaps @@ -63,33 +55,6 @@ export function registerCommands() { } }); - 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; @@ -161,12 +126,6 @@ export function registerCommands() { autoCompleteProvider.triggerAutocompletePlus(); }); - 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(); @@ -346,7 +305,6 @@ export function registerCommands() { showProjectSymbols(filePath); }); - atomUtils.registerOpener({ commandSelector: 'atom-text-editor', commandName: 'typescript:ast', @@ -391,18 +349,6 @@ export function registerCommands() { } }); - 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; 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/views/contextView.ts b/lib/main/atom/views/contextView.ts index 107d915aa..10f9d4677 100644 --- a/lib/main/atom/views/contextView.ts +++ b/lib/main/atom/views/contextView.ts @@ -1,6 +1,5 @@ import sp = require('atom-space-pen-views'); import mainPanelView = require('./mainPanelView'); -import * as semanticView from "./semanticView"; interface ContextViewItem { title: string; @@ -11,7 +10,6 @@ var titles = { 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] } }); @@ -46,9 +44,6 @@ export class ContextView extends sp.SelectListView { if (item.title == titles.tabReferences) { mainPanelView.panelView.referencesPanelSelected(); } - if (item.title == titles.fileSemantics){ - semanticView.toggle(); - } 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/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/atomts.ts b/lib/main/atomts.ts index bb5c24c17..944381565 100644 --- a/lib/main/atomts.ts +++ b/lib/main/atomts.ts @@ -1,4 +1,5 @@ console.log("be initializing them package") +console.profile("atomts init") const start = process.hrtime() import atomConfig = require('./atom/atomConfig'); @@ -8,6 +9,7 @@ makeTsGlobal(atomConfig.typescriptServices); import path = require('path'); import fs = require('fs'); import os = require('os'); +import * as _ from "lodash" import {errorView} from "./atom/views/mainPanelView"; @@ -32,7 +34,6 @@ 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"); @@ -43,8 +44,7 @@ var statusBarMessage; var editorWatch: AtomCore.Disposable; var autoCompleteWatch: AtomCore.Disposable; -export interface PackageState { -} +export interface PackageState {} import parent = require('../worker/parent'); @@ -52,6 +52,10 @@ import parent = require('../worker/parent'); export var config = atomConfig.schema; import {debounce} from "./lang/utils"; +import {LinterRegistry, Linter} from "../linter" + +let linter: Linter + var hideIfNotActiveOnStart = debounce(() => { // Only show if this editor is active: var editor = atom.workspace.getActiveTextEditor(); @@ -60,12 +64,7 @@ var hideIfNotActiveOnStart = debounce(() => { } }, 100); - -var __onlyOnce = false; -function onlyOnceStuff() { - if (__onlyOnce) return; - else __onlyOnce = true; - +const attachViews = _.once(() => { mainPanelView.attach(); // Add the documentation view @@ -73,41 +72,17 @@ function onlyOnceStuff() { // Add the rename view renameView.attach(); - - semanticView.attach(); -} +}) /** 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(); + attachViews() updatePanelConfig(filePath); // // Refresh errors stuff on change active tab. @@ -178,7 +153,7 @@ function readyToActivate() { let isTst = ext === '.tst'; try { // Only once stuff - onlyOnceStuff(); + attachViews() client.executeOpen({ file: filePath, @@ -371,19 +346,25 @@ export function deserialize() { /* do any tear down here */ } +export function consumeLinter(registry: LinterRegistry) { + console.log("consume this") + + linter = registry.register({ + name: "Typescript" + }) + + console.log("got linter", linter) +} + // Registering an autocomplete provider export function provide() { return [autoCompleteProvider.provider]; } -import * as linter from "../linter"; -export function provideLinter() { - return linter.provider; -} - import * as hyperclickProvider from "../hyperclickProvider"; export function getHyperclickProvider() { return hyperclickProvider; } -console.log("init took", process.hrtime(start)) \ No newline at end of file +console.profileEnd() +console.log("init took", process.hrtime(start)) 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/lang/modules/building.ts b/lib/main/lang/modules/building.ts index 1ae8a762e..ad4708019 100644 --- a/lib/main/lang/modules/building.ts +++ b/lib/main/lang/modules/building.ts @@ -7,11 +7,6 @@ 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 */"; @@ -29,69 +24,6 @@ export function diagnosticToTSError(diagnostic: ts.Diagnostic): CodeError { }; } -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; @@ -106,143 +38,6 @@ export function getRawOutput(proj: project.Project, filePath: string): ts.EmitOu 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"); } diff --git a/lib/main/lang/projectService.ts b/lib/main/lang/projectService.ts index ae623ae38..cd3f747f0 100644 --- a/lib/main/lang/projectService.ts +++ b/lib/main/lang/projectService.ts @@ -91,76 +91,6 @@ export function quickInfo(query: QuickInfoQuery): Promise { } } -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; } @@ -291,14 +221,6 @@ export function getSignatureHelps(query: GetSignatureHelpQuery): PromisesignatureHelpItems.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 { } @@ -391,50 +313,6 @@ function getDiagnositcsByFilePath(query: FilePathQuery) { 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; @@ -902,64 +780,11 @@ export function applyQuickFix(query: ApplyQuickFixQuery): 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<{}> { + console.log("Resetting..") resetCache(query); return resolve({}); } diff --git a/lib/main/tsconfig/tsconfig.ts b/lib/main/tsconfig/tsconfig.ts index 427325be9..78b3a28e2 100644 --- a/lib/main/tsconfig/tsconfig.ts +++ b/lib/main/tsconfig/tsconfig.ts @@ -257,7 +257,6 @@ 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'; diff --git a/lib/tsd.json b/lib/tsd.json index 908b7101c..803fc88c9 100644 --- a/lib/tsd.json +++ b/lib/tsd.json @@ -35,15 +35,6 @@ "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/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/tsd.d.ts b/lib/typings/tsd.d.ts index e6cae6543..cb51874b4 100644 --- a/lib/typings/tsd.d.ts +++ b/lib/typings/tsd.d.ts @@ -2,7 +2,4 @@ /// /// /// -/// -/// -/// /// diff --git a/lib/worker/parent.ts b/lib/worker/parent.ts index 6014eb19d..b112b6301 100644 --- a/lib/worker/parent.ts +++ b/lib/worker/parent.ts @@ -62,18 +62,15 @@ function catchCommonErrors(func: workerLib.QRFunction=0.199.0 <2.0.0", "node": "*" }, + "consumedServices": { + "linter-indie": { + "versions": { + "^1.0.0": "consumeLinter" + } + } + }, "providedServices": { "autocomplete.provider": { "versions": { @@ -49,7 +55,6 @@ "@types/resolve": "0.0.4", "atom-package-deps": "^2.0.3", "atom-space-pen-views": "^2.0.4", - "babel": "^5.6.23", "basarat-text-buffer": "6.0.0", "byline": "^5.0.0", "byots": "2.2.0-dev.20161129.23.20", @@ -64,14 +69,13 @@ "htmltojsx": "0.2.4", "immutable": "^3.7.3", "json2dts": "0.0.1", + "lodash": "4.17.2", "mkdirp": "^0.5.0", - "react": "^0.13.3", "resolve": "1.1.7", "season": "^5.1.4", "tsconfig": "^2.2.0", "tslib": "1.2.0", - "typescript": "2.2.0-dev.20161130", - "xtend": "^4.0.0" + "typescript": "2.2.0-dev.20161130" }, "devDependencies": { "@types/cson": "0.0.30", From 46f6e052653149ea6267f6d7e5e6b34b31a2ae8e Mon Sep 17 00:00:00 2001 From: Guntars Asmanis-Graham Date: Wed, 30 Nov 2016 22:41:59 -0500 Subject: [PATCH 15/70] Delete all the things --- dist/hyperclickProvider.js | 15 - dist/main/atom/atomConfig.js | 13 - dist/main/atom/atomUtils.js | 1 - dist/main/atom/autoCompleteProvider.js | 11 - dist/main/atom/commands/commands.js | 229 ----- dist/main/atom/commands/json2dtsCommands.js | 2 - dist/main/atom/tooltipManager.js | 3 - dist/main/atom/views/dependencyView.js | 1 - dist/main/atom/views/mainPanelView.js | 3 +- dist/main/atom/views/plainMessageView.js | 1 - dist/main/atomts.js | 38 +- dist/main/lang/core/languageServiceHost2.js | 1 - dist/main/lang/projectService.js | 240 ----- dist/worker/parent.js | 67 +- lib/client/client.ts | 4 +- lib/client/clientResolver.ts | 1 - lib/hyperclickProvider.ts | 30 +- lib/main/atom/atomConfig.ts | 6 - lib/main/atom/atomUtils.ts | 2 - lib/main/atom/autoCompleteProvider.ts | 28 - lib/main/atom/buildView.ts | 66 -- lib/main/atom/commands/commands.ts | 459 ++++----- lib/main/atom/commands/json2dtsCommands.ts | 19 - lib/main/atom/debugAtomTs.ts | 18 - lib/main/atom/editorSetup.ts | 63 -- lib/main/atom/fileStatusCache.ts | 1 - lib/main/atom/onSaveHandler.ts | 64 -- lib/main/atom/signatureProvider.ts | 26 - lib/main/atom/tooltipManager.ts | 6 - lib/main/atom/typescriptGrammar.ts | 307 ------ lib/main/atom/views/astView.ts | 203 ---- lib/main/atom/views/awesomePanelView.ts | 29 - lib/main/atom/views/dependencyView.ts | 521 ---------- lib/main/atom/views/fileSymbolsView.ts | 6 +- lib/main/atom/views/lineMessageView.ts | 1 - lib/main/atom/views/mainPanelView.ts | 8 - lib/main/atom/views/plainMessageView.ts | 2 - lib/main/atom/views/projectSymbolsView.ts | 2 - .../atom/views/simpleOverlaySelectionView.ts | 1 - lib/main/atom/views/simpleSelectionView.ts | 5 +- lib/main/atomts.ts | 66 +- lib/main/json2dts/json2dts.ts | 21 - lib/main/lang/core/languageServiceHost2.ts | 392 -------- lib/main/lang/core/project.ts | 57 -- lib/main/lang/fixmyts/quickFix.ts | 79 -- lib/main/lang/fixmyts/quickFixRegistry.ts | 34 - .../lang/fixmyts/quickFixes/addClassMember.ts | 122 --- .../lang/fixmyts/quickFixes/addClassMethod.ts | 252 ----- .../quickFixes/addImportFromStatement.ts | 84 -- .../fixmyts/quickFixes/addImportStatement.ts | 84 -- .../lang/fixmyts/quickFixes/equalsToEquals.ts | 38 - .../fixmyts/quickFixes/extractVariable.ts | 218 ----- .../fixmyts/quickFixes/implementInterface.ts | 75 -- .../fixmyts/quickFixes/quoteToTemplate.ts | 43 - .../lang/fixmyts/quickFixes/quotesToQuotes.ts | 47 - .../quickFixes/singleLineCommentToJsdoc.ts | 50 - .../quickFixes/stringConcatToTemplate.ts | 123 --- .../typeAssertPropertyAccessToAny.ts | 58 -- .../typeAssertPropertyAccessToType.ts | 59 -- .../lang/fixmyts/quickFixes/wrapInProperty.ts | 123 --- lib/main/lang/modules/building.ts | 106 -- lib/main/lang/modules/formatting.ts | 29 - lib/main/lang/modules/getPathCompletions.ts | 78 -- lib/main/lang/modules/moveFiles.ts | 59 -- lib/main/lang/modules/programDependencies.ts | 36 - lib/main/lang/projectCache.ts | 238 ----- lib/main/lang/projectService.ts | 887 ----------------- .../implementations/nullTransformer.ts | 12 - lib/main/lang/transformers/transformer.ts | 101 -- .../lang/transformers/transformerRegistry.ts | 80 -- lib/main/lang/typescriptServices.ts | 5 - lib/main/tsconfig/dts-generator.ts | 237 ----- lib/main/tsconfig/simpleValidator.ts | 85 -- lib/main/tsconfig/tsconfig.ts | 908 ------------------ lib/tsconfig.json | 1 + lib/typescript/makeTypeScriptGlobal.ts | 21 - lib/worker/child.ts | 25 - lib/worker/lib/workerLib.ts | 346 ------- lib/worker/parent.ts | 96 +- lib/worker/queryParent.ts | 125 --- 80 files changed, 244 insertions(+), 7759 deletions(-) delete mode 100644 lib/main/atom/buildView.ts delete mode 100644 lib/main/atom/commands/json2dtsCommands.ts delete mode 100644 lib/main/atom/debugAtomTs.ts delete mode 100644 lib/main/atom/editorSetup.ts delete mode 100644 lib/main/atom/onSaveHandler.ts delete mode 100644 lib/main/atom/signatureProvider.ts delete mode 100644 lib/main/atom/typescriptGrammar.ts delete mode 100644 lib/main/atom/views/astView.ts delete mode 100644 lib/main/atom/views/awesomePanelView.ts delete mode 100644 lib/main/atom/views/dependencyView.ts delete mode 100644 lib/main/json2dts/json2dts.ts delete mode 100644 lib/main/lang/core/languageServiceHost2.ts delete mode 100644 lib/main/lang/core/project.ts delete mode 100644 lib/main/lang/fixmyts/quickFix.ts delete mode 100644 lib/main/lang/fixmyts/quickFixRegistry.ts delete mode 100644 lib/main/lang/fixmyts/quickFixes/addClassMember.ts delete mode 100644 lib/main/lang/fixmyts/quickFixes/addClassMethod.ts delete mode 100644 lib/main/lang/fixmyts/quickFixes/addImportFromStatement.ts delete mode 100644 lib/main/lang/fixmyts/quickFixes/addImportStatement.ts delete mode 100644 lib/main/lang/fixmyts/quickFixes/equalsToEquals.ts delete mode 100644 lib/main/lang/fixmyts/quickFixes/extractVariable.ts delete mode 100644 lib/main/lang/fixmyts/quickFixes/implementInterface.ts delete mode 100644 lib/main/lang/fixmyts/quickFixes/quoteToTemplate.ts delete mode 100644 lib/main/lang/fixmyts/quickFixes/quotesToQuotes.ts delete mode 100644 lib/main/lang/fixmyts/quickFixes/singleLineCommentToJsdoc.ts delete mode 100644 lib/main/lang/fixmyts/quickFixes/stringConcatToTemplate.ts delete mode 100644 lib/main/lang/fixmyts/quickFixes/typeAssertPropertyAccessToAny.ts delete mode 100644 lib/main/lang/fixmyts/quickFixes/typeAssertPropertyAccessToType.ts delete mode 100644 lib/main/lang/fixmyts/quickFixes/wrapInProperty.ts delete mode 100644 lib/main/lang/modules/building.ts delete mode 100644 lib/main/lang/modules/formatting.ts delete mode 100644 lib/main/lang/modules/getPathCompletions.ts delete mode 100644 lib/main/lang/modules/moveFiles.ts delete mode 100644 lib/main/lang/modules/programDependencies.ts delete mode 100644 lib/main/lang/projectCache.ts delete mode 100644 lib/main/lang/projectService.ts delete mode 100644 lib/main/lang/transformers/implementations/nullTransformer.ts delete mode 100644 lib/main/lang/transformers/transformer.ts delete mode 100644 lib/main/lang/transformers/transformerRegistry.ts delete mode 100644 lib/main/lang/typescriptServices.ts delete mode 100644 lib/main/tsconfig/dts-generator.ts delete mode 100644 lib/main/tsconfig/simpleValidator.ts delete mode 100644 lib/main/tsconfig/tsconfig.ts delete mode 100644 lib/typescript/makeTypeScriptGlobal.ts delete mode 100644 lib/worker/child.ts delete mode 100644 lib/worker/lib/workerLib.ts delete mode 100644 lib/worker/queryParent.ts diff --git a/dist/hyperclickProvider.js b/dist/hyperclickProvider.js index 8cc4b58e2..796650bec 100644 --- a/dist/hyperclickProvider.js +++ b/dist/hyperclickProvider.js @@ -1,6 +1,4 @@ "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"; @@ -12,19 +10,6 @@ function getSuggestionForWord(textEditor, text, range) { 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 - }); - } - }); } }; } diff --git a/dist/main/atom/atomConfig.js b/dist/main/atom/atomConfig.js index f8b9811fb..891e8b148 100644 --- a/dist/main/atom/atomConfig.js +++ b/dist/main/atom/atomConfig.js @@ -10,11 +10,6 @@ function setConfig(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', @@ -32,14 +27,6 @@ var Config = (function () { } }; } - 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; diff --git a/dist/main/atom/atomUtils.js b/dist/main/atom/atomUtils.js index a45ee829b..3b75c3bfa 100644 --- a/dist/main/atom/atomUtils.js +++ b/dist/main/atom/atomUtils.js @@ -89,7 +89,6 @@ function getEditorsForAllPaths(filePaths) { } 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); diff --git a/dist/main/atom/autoCompleteProvider.js b/dist/main/atom/autoCompleteProvider.js index c64cc35aa..c64e03f20 100644 --- a/dist/main/atom/autoCompleteProvider.js +++ b/dist/main/atom/autoCompleteProvider.js @@ -9,17 +9,6 @@ function triggerAutocompletePlus() { explicitlyTriggered = true; } exports.triggerAutocompletePlus = triggerAutocompletePlus; -function getModuleAutocompleteType(scopes) { - function has(match) { - return scopes.some(function (scope) { return scope.indexOf(match) !== -1; }); - } - 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, diff --git a/dist/main/atom/commands/commands.js b/dist/main/atom/commands/commands.js index 86b1fcf60..06b9c814a 100644 --- a/dist/main/atom/commands/commands.js +++ b/dist/main/atom/commands/commands.js @@ -5,94 +5,12 @@ function __export(m) { var parent = require("../../../worker/parent"); 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 escapeHtml = require("escape-html"); -var json2dtsCommands_1 = require("./json2dtsCommands"); __export(require("../components/componentRegistry")); function registerCommands() { - json2dtsCommands_1.registerJson2dtsCommands(); - 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); - }); - }); - } - }); - var handleGoToDeclaration = function (e) { - if (!atomUtils.commandForTypeScript(e)) - return; - 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) { - atom.workspace.open(definition.filePath, { - initialLine: definition.position.line, - initialColumn: definition.position.col - }); - } - }); - } - else { - var definition = definitions[0]; - atom.workspace.open(definition.filePath, { - initialLine: definition.position.line, - initialColumn: definition.position.col - }); - } - }); - }; - 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: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) @@ -102,54 +20,6 @@ function registerCommands() { atom.commands.add('atom-text-editor', 'typescript:autocomplete', function (e) { autoCompleteProvider.triggerAutocompletePlus(); }); - atom.commands.add('atom-text-editor', 'typescript:rename-refactor', function (e) { - var editor = atom.workspace.getActiveTextEditor(); - if (true) { - 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); @@ -190,105 +60,6 @@ function registerCommands() { 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('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-workspace', 'typescript:sync', function (e) { if (!atomUtils.commandForTypeScript(e)) return; diff --git a/dist/main/atom/commands/json2dtsCommands.js b/dist/main/atom/commands/json2dtsCommands.js index 4fd16c14a..7c2ede9bf 100644 --- a/dist/main/atom/commands/json2dtsCommands.js +++ b/dist/main/atom/commands/json2dtsCommands.js @@ -6,8 +6,6 @@ function registerJson2dtsCommands() { 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)); diff --git a/dist/main/atom/tooltipManager.js b/dist/main/atom/tooltipManager.js index 98b855110..e265bb961 100644 --- a/dist/main/atom/tooltipManager.js +++ b/dist/main/atom/tooltipManager.js @@ -107,6 +107,3 @@ 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)); -} diff --git a/dist/main/atom/views/dependencyView.js b/dist/main/atom/views/dependencyView.js index 97ddd60c0..8b09e64b7 100644 --- a/dist/main/atom/views/dependencyView.js +++ b/dist/main/atom/views/dependencyView.js @@ -273,7 +273,6 @@ function renderGraph(dependencies, mainContent, display) { var D3Graph = (function () { function D3Graph(links) { var _this = this; - this.links = links; this.inDegLookup = {}; this.outDegLookup = {}; this.linkedByName = {}; diff --git a/dist/main/atom/views/mainPanelView.js b/dist/main/atom/views/mainPanelView.js index 9c51994ad..a79a9d2bd 100644 --- a/dist/main/atom/views/mainPanelView.js +++ b/dist/main/atom/views/mainPanelView.js @@ -1,7 +1,6 @@ "use strict"; var tslib_1 = require("tslib"); var view = require("./view"); -var $ = view.$; var lineMessageView = require("./lineMessageView"); var atomUtils = require("../atomUtils"); var utils = require("../../lang/utils"); @@ -290,7 +289,7 @@ var MainPanelView = (function (_super) { this.errorBody.append(view.$); }; MainPanelView.prototype.setErrorSummary = function (summary) { - var message = summary.summary, className = summary.className, raw = summary.rawSummary || false, handler = summary.handler || undefined; + var message = summary.summary, className = summary.className, handler = summary.handler || undefined; this.summary.html(message); if (className) { this.summary.addClass(className); diff --git a/dist/main/atom/views/plainMessageView.js b/dist/main/atom/views/plainMessageView.js index e036b6f30..d370eb1d8 100644 --- a/dist/main/atom/views/plainMessageView.js +++ b/dist/main/atom/views/plainMessageView.js @@ -1,7 +1,6 @@ "use strict"; var tslib_1 = require("tslib"); var view = require("./view"); -var $ = view.$; var PlainMessageView = (function (_super) { tslib_1.__extends(PlainMessageView, _super); function PlainMessageView() { diff --git a/dist/main/atomts.js b/dist/main/atomts.js index 75b54c712..fe6bb10c5 100644 --- a/dist/main/atomts.js +++ b/dist/main/atomts.js @@ -3,26 +3,22 @@ var tslib_1 = require("tslib"); console.log("be initializing them package"); console.profile("atomts init"); var start = process.hrtime(); -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 _ = require("lodash"); +var _atom = require("atom"); +var atom_space_pen_views_1 = require("atom-space-pen-views"); var mainPanelView_1 = require("./atom/views/mainPanelView"); -var autoCompleteProvider = require("./atom/autoCompleteProvider"); -var tooltipManager = require("./atom/tooltipManager"); +var fileStatusCache_1 = require("./atom/fileStatusCache"); +var _ = require("lodash"); +var hyperclickProvider = require("../hyperclickProvider"); +var atomConfig = require("./atom/atomConfig"); var atomUtils = require("./atom/atomUtils"); +var autoCompleteProvider = require("./atom/autoCompleteProvider"); var commands = require("./atom/commands/commands"); -var debugAtomTs = require("./atom/debugAtomTs"); -var _atom = require("atom"); -var atom_space_pen_views_1 = require("atom-space-pen-views"); var documentationView = require("./atom/views/documentationView"); -var renameView = require("./atom/views/renameView"); +var fs = require("fs"); var mainPanelView = require("./atom/views/mainPanelView"); -var fileStatusCache_1 = require("./atom/fileStatusCache"); -var editorSetup = require("./atom/editorSetup"); -var statusBar; +var path = require("path"); +var renameView = require("./atom/views/renameView"); +var tooltipManager = require("./atom/tooltipManager"); var statusBarMessage; var editorWatch; var autoCompleteWatch; @@ -59,7 +55,7 @@ function readyToActivate() { }); editorWatch = atom.workspace.observeTextEditors(function (editor) { return tslib_1.__awaiter(this, void 0, void 0, function () { - var filePath, client, editorView, ext, unsubSyntax_1, unsubSemantic_1, isTst, onDisk, changeObserver, buffer, fasterChangeObserver, saveObserver, destroyObserver; + var filePath, client, editorView, ext, unsubSyntax_1, unsubSemantic_1, onDisk, changeObserver, fasterChangeObserver, saveObserver, destroyObserver; return tslib_1.__generator(this, function (_a) { switch (_a.label) { case 0: @@ -90,7 +86,6 @@ function readyToActivate() { })); } }); - isTst = ext === '.tst'; try { attachViews(); client.executeOpen({ @@ -103,11 +98,9 @@ function readyToActivate() { onDisk = true; } hideIfNotActiveOnStart(); - debugAtomTs.runDebugCode({ filePath: filePath, editor: editor }); if (onDisk) { client.executeGetErr({ files: [filePath], delay: 100 }); } - editorSetup.setupEditor(editor); changeObserver = editor.onDidStopChanging(function () { if (editor === atom.workspace.getActiveTextEditor()) { var status_1 = fileStatusCache_1.getFileStatus(filePath); @@ -121,7 +114,6 @@ function readyToActivate() { } client.executeGetErr({ files: [filePath], delay: 100 }); }); - buffer = editor.buffer; fasterChangeObserver = editor.buffer.onDidChange(function (diff) { client.executeChange({ endLine: diff.oldRange.end.row + 1, @@ -180,6 +172,7 @@ function activate(state) { console.log("observed grammar", grammar); }); }); + require('atom-package-deps').install('atom-typescript').then(readyToActivate); } exports.activate = activate; function deactivate() { @@ -189,16 +182,12 @@ function deactivate() { editorWatch.dispose(); if (autoCompleteWatch) autoCompleteWatch.dispose(); - parent.stopWorker(); } exports.deactivate = deactivate; function serialize() { return {}; } exports.serialize = serialize; -function deserialize() { -} -exports.deserialize = deserialize; function consumeLinter(registry) { console.log("consume this"); linter = registry.register({ @@ -211,7 +200,6 @@ function provide() { return [autoCompleteProvider.provider]; } exports.provide = provide; -var hyperclickProvider = require("../hyperclickProvider"); function getHyperclickProvider() { return hyperclickProvider; } diff --git a/dist/main/lang/core/languageServiceHost2.js b/dist/main/lang/core/languageServiceHost2.js index e124b343d..789267d6a 100644 --- a/dist/main/lang/core/languageServiceHost2.js +++ b/dist/main/lang/core/languageServiceHost2.js @@ -70,7 +70,6 @@ function createScriptInfo(fileName, text, isOpen) { }; } function getScriptSnapShot(scriptInfo) { - var lineStarts = scriptInfo.getLineStarts(); var textSnapshot = scriptInfo.getContent(); var version = scriptInfo.getVersion(); var editRanges = scriptInfo.getEditRanges(); diff --git a/dist/main/lang/projectService.js b/dist/main/lang/projectService.js index 3afded94c..0904e2d53 100644 --- a/dist/main/lang/projectService.js +++ b/dist/main/lang/projectService.js @@ -1,11 +1,6 @@ "use strict"; -var fsu = require("../utils/fsUtil"); var path = require("path"); -var os = require("os"); -var fuzzaldrin = require('fuzzaldrin'); -var transformer = require("./transformers/transformer"); var tsconfig = require("../tsconfig/tsconfig"); -var utils = require("./utils"); var resolve = Promise.resolve.bind(Promise); var projectCache_1 = require("./projectCache"); function textSpan(span) { @@ -40,78 +35,6 @@ function quickInfo(query) { } } exports.quickInfo = quickInfo; -function getCompletionsAtPosition(query) { - projectCache_1.consistentPath(query); - var filePath = query.filePath, position = query.position, prefix = query.prefix; - var project = projectCache_1.getOrCreateProject(filePath); - filePath = transformer.getPseudoFilePath(filePath); - var completions = project.languageService.getCompletionsAtPosition(filePath, position); - var completionList = completions ? completions.entries.filter(function (x) { return !!x; }) : []; - var endsInPunctuation = utils.prefixEndsInPunctuation(prefix); - if (prefix.length && !endsInPunctuation) { - completionList = fuzzaldrin.filter(completionList, prefix, { key: 'name' }); - } - var maxSuggestions = 50; - var maxDocComments = 10; - if (completionList.length > maxSuggestions) - completionList = completionList.slice(0, maxSuggestions); - function docComment(c) { - var completionDetails = project.languageService.getCompletionEntryDetails(filePath, position, c.name); - var display; - if (c.kind == "method" || c.kind == "function" || c.kind == "property") { - var parts = completionDetails.displayParts || []; - 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 = completionList.map(function (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(function (item) { - var snippet = item.parameters.map(function (p, i) { - var display = '${' + (i + 1) + ':' + ts.displayPartsToString(p.displayParts) + '}'; - if (i === signatures.argumentIndex) { - return display; - } - return display; - }).join(ts.displayPartsToString(item.separatorDisplayParts)); - var label = ts.displayPartsToString(item.prefixDisplayParts) - + snippet - + ts.displayPartsToString(item.suffixDisplayParts); - completionsToReturn.unshift({ snippet: snippet }); - }); - } - } - return resolve({ - completions: completionsToReturn, - endsInPunctuation: endsInPunctuation - }); -} -exports.getCompletionsAtPosition = getCompletionsAtPosition; function getSignatureHelps(query) { projectCache_1.consistentPath(query); var project = projectCache_1.getOrCreateProject(query.filePath); @@ -153,34 +76,6 @@ function getDefinitionsAtPosition(query) { }); } exports.getDefinitionsAtPosition = getDefinitionsAtPosition; -function updateText(query) { - projectCache_1.consistentPath(query); - var lsh = projectCache_1.getOrCreateProject(query.filePath).languageServiceHost; - var filePath = transformer.getPseudoFilePath(query.filePath); - lsh.updateScript(filePath, query.text); - return resolve({}); -} -exports.updateText = updateText; -function editText(query) { - projectCache_1.consistentPath(query); - var project = projectCache_1.getOrCreateProject(query.filePath); - if (project.includesSourceFile(query.filePath)) { - var lsh = project.languageServiceHost; - var filePath = transformer.getPseudoFilePath(query.filePath); - lsh.editScript(filePath, query.start, query.end, query.newText); - } - return resolve({}); -} -exports.editText = editText; -function getDiagnositcsByFilePath(query) { - projectCache_1.consistentPath(query); - var project = projectCache_1.getOrCreateProject(query.filePath); - var diagnostics = project.languageService.getSyntacticDiagnostics(query.filePath); - if (diagnostics.length === 0) { - diagnostics = project.languageService.getSemanticDiagnostics(query.filePath); - } - return diagnostics; -} function getRenameInfo(query) { projectCache_1.consistentPath(query); var project = projectCache_1.getOrCreateProject(query.filePath); @@ -298,7 +193,6 @@ 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; function getDeclarationName(declaration) { var result = getTextOfIdentifierOrLiteral(declaration.name); @@ -359,10 +253,6 @@ function getReferences(query) { } exports.getReferences = getReferences; var getPathCompletions_1 = require("./modules/getPathCompletions"); -function filePathWithoutExtension(query) { - var base = path.basename(query, '.ts'); - return path.dirname(query) + '/' + base; -} function getRelativePathsInProject(query) { projectCache_1.consistentPath(query); var project = projectCache_1.getOrCreateProject(query.filePath); @@ -408,89 +298,6 @@ function getDependencies(query) { return resolve({ links: links }); } exports.getDependencies = getDependencies; -var qf = require("./fixmyts/quickFix"); -var 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; - 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); - } - else { - sourceFileText = ""; - fileErrors = []; - positionErrors = []; - positionErrorMessages = []; - positionNode = undefined; - } - var service = project.languageService; - var typeChecker = program.getTypeChecker(); - return { - project: project, - program: program, - sourceFile: sourceFile, - sourceFileText: sourceFileText, - fileErrors: fileErrors, - positionErrors: positionErrors, - positionErrorMessages: positionErrorMessages, - position: query.position, - positionNode: positionNode, - service: service, - typeChecker: typeChecker, - filePath: query.filePath - }; -} -function getQuickFixes(query) { - projectCache_1.consistentPath(query); - var project = projectCache_1.getOrCreateProject(query.filePath); - if (!project.includesSourceFile(query.filePath)) { - return resolve({ fixes: [] }); - } - var info = getInfoForQuickFixAnalysis(query); - var fixes = quickFixRegistry_1.allQuickFixes - .map(function (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 }); -} -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 info = getInfoForQuickFixAnalysis(query); - var res = fix.provideFix(info); - var refactorings = qf.getRefactoringsByFilePath(res); - return resolve({ refactorings: refactorings }); -} -exports.applyQuickFix = applyQuickFix; -function softReset(query) { - console.log("Resetting.."); - projectCache_1.resetCache(query); - return resolve({}); -} -exports.softReset = softReset; -var 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 }); -} -exports.getRenameFilesRefactorings = getRenameFilesRefactorings; function createProject(query) { projectCache_1.consistentPath(query); var projectFile = tsconfig.createProjectRootSync(query.filePath); @@ -498,50 +305,3 @@ function createProject(query) { return resolve({ createdFilePath: projectFile.projectFilePath }); } 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; - if (positionNode.kind != ts.SyntaxKind.DebuggerKeyword && positionNode.getFullStart() > 0) { - var previousNode = ts.getTokenAtPosition(sourceFile, positionNode.getFullStart() - 1); - if (previousNode.kind == ts.SyntaxKind.DebuggerStatement) { - positionNode = previousNode; - } - if (previousNode.parent && previousNode.parent.kind == ts.SyntaxKind.DebuggerStatement) { - positionNode = previousNode.parent; - } - } - if (positionNode.kind == ts.SyntaxKind.DebuggerKeyword || positionNode.kind == ts.SyntaxKind.DebuggerStatement) { - var start = positionNode.getFullStart(); - var end = start + positionNode.getFullWidth(); - while (end < sourceFileText.length && sourceFileText[end] == ';') { - end = end + 1; - } - refactoring = { - filePath: query.filePath, - span: { - start: start, - length: end - start - }, - newText: '' - }; - } - else { - var toInsert = 'debugger;'; - refactoring = { - filePath: query.filePath, - span: { - start: positionNode.getFullStart(), - length: 0 - }, - newText: toInsert - }; - } - var refactorings = qf.getRefactoringsByFilePath(refactoring ? [refactoring] : []); - return resolve({ refactorings: refactorings }); -} -exports.toggleBreakpoint = toggleBreakpoint; diff --git a/dist/worker/parent.js b/dist/worker/parent.js index e783ab632..53496ec7f 100644 --- a/dist/worker/parent.js +++ b/dist/worker/parent.js @@ -1,72 +1,7 @@ "use strict"; -var debug_1 = require("./debug"); -var tsconfig = require("tsconfig/dist/tsconfig"); -var workerLib = require("./lib/workerLib"); -var atomConfig = require("../main/atom/atomConfig"); var clientResolver_1 = require("../client/clientResolver"); -var parent = new workerLib.Parent(); var mainPanel = require("../main/atom/views/mainPanelView"); -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.getCompletionsAtPosition = parent.sendToIpcOnlyLast(projectService.getCompletionsAtPosition, { - completions: [], - endsInPunctuation: false -}); -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.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.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.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); +var tsconfig = require("tsconfig/dist/tsconfig"); exports.clients = new clientResolver_1.ClientResolver(); exports.clients.on("pendingRequestsChange", function () { if (!mainPanel.panelView) diff --git a/lib/client/client.ts b/lib/client/client.ts index 5a3be8312..f39f9b1e2 100644 --- a/lib/client/client.ts +++ b/lib/client/client.ts @@ -1,6 +1,6 @@ import {ChildProcess, spawn} from "child_process" -import {EventEmitter} from "events" import {Transform, Readable} from "stream" +import * as protocol from "typescript/lib/protocol" import byline = require("byline") export class TypescriptServiceClient { @@ -27,8 +27,6 @@ export class TypescriptServiceClient { /** Promise that resolves when the server is ready to accept requests */ serverPromise: Promise - private serverDeferred: {resolve(), reject()} - /** Path to the tsserver executable */ readonly tsServerPath: string diff --git a/lib/client/clientResolver.ts b/lib/client/clientResolver.ts index 36b95bc39..32a2cb7a5 100644 --- a/lib/client/clientResolver.ts +++ b/lib/client/clientResolver.ts @@ -1,6 +1,5 @@ import {TypescriptServiceClient as Client} from "./client" import * as events from "events" -import * as fs from "fs" import * as path from "path" import * as nodeResolve from "resolve" diff --git a/lib/hyperclickProvider.ts b/lib/hyperclickProvider.ts index d47220e43..537c3feca 100644 --- a/lib/hyperclickProvider.ts +++ b/lib/hyperclickProvider.ts @@ -1,5 +1,5 @@ -import * as parent from "./worker/parent"; -import * as atomUtils from "./main/atom/atomUtils"; +// 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"]); @@ -16,20 +16,20 @@ export function getSuggestionForWord(textEditor: AtomCore.IEditor, text: string, return { range: range, callback() { - let filePathPosition = { - filePath: textEditor.getPath(), - position: atomUtils.getEditorPositionForBufferPosition(textEditor, range.start) - }; + // 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 - }); - } - }); + // 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/main/atom/atomConfig.ts b/lib/main/atom/atomConfig.ts index c9525a5cd..692e8b0c4 100644 --- a/lib/main/atom/atomConfig.ts +++ b/lib/main/atom/atomConfig.ts @@ -15,11 +15,6 @@ function setConfig(nameLambda: () => any, value: T): T { class Config { schema = { - debugAtomTs: { - title: 'Debug: Atom-TypeScript. Please do not use.', - type: 'boolean', - default: false - }, preferredQuoteCharacter: { title: 'Preferred quote character', type: 'string', @@ -36,7 +31,6 @@ class Config { 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) } diff --git a/lib/main/atom/atomUtils.ts b/lib/main/atom/atomUtils.ts index b691a989b..ece3f3dd7 100644 --- a/lib/main/atom/atomUtils.ts +++ b/lib/main/atom/atomUtils.ts @@ -2,7 +2,6 @@ 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 @@ -98,7 +97,6 @@ export function getEditorsForAllPaths(filePaths: string[]): Promise<{ [filePath: } 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); diff --git a/lib/main/atom/autoCompleteProvider.ts b/lib/main/atom/autoCompleteProvider.ts index d1febdb94..78cb7b296 100644 --- a/lib/main/atom/autoCompleteProvider.ts +++ b/lib/main/atom/autoCompleteProvider.ts @@ -1,7 +1,6 @@ // more: https://github.com/atom-community/autocomplete-plus/wiki/Provider-API -import atomConfig = require('./atomConfig') import atomUtils = require('./atomUtils') import fs = require('fs') import parent = require('../../worker/parent') @@ -51,33 +50,6 @@ export function triggerAutocompletePlus() { explicitlyTriggered = true; } -// the structure stored in the CSON snippet file -interface SnippetDescriptor { - prefix: string; - body: string; -} -interface SnippetsContianer { - [name: string]: SnippetDescriptor; -} - -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) - } - - let 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 - } -} - export var provider: autocompleteplus.Provider = { selector: '.source.ts, .source.tsx', inclusionPriority: 3, 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/commands.ts b/lib/main/atom/commands/commands.ts index 2b851d8b5..935a62331 100644 --- a/lib/main/atom/commands/commands.ts +++ b/lib/main/atom/commands/commands.ts @@ -1,120 +1,103 @@ 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 path = require('path'); +// import renameView = require("../views/renameView"); import contextView = require("../views/contextView"); -import fileSymbolsView = require("../views/fileSymbolsView"); -import projectSymbolsView = require("../views/projectSymbolsView"); +// 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 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 {RefactoringsByFilePath} from "../../lang/fixmyts/quickFix"; -import escapeHtml = require('escape-html'); -import {$} from "atom-space-pen-views"; -import {getFileStatus} from "../fileStatusCache"; -import {registerJson2dtsCommands} from "./json2dtsCommands"; +// import {simpleSelectionView} from "../views/simpleSelectionView"; +// import escapeHtml = require('escape-html'); // Load all the web components export * from "../components/componentRegistry"; export function registerCommands() { - // Stuff I've split out as we have a *lot* of commands - registerJson2dtsCommands(); - // 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); - }); - }); - - } - }); - - var handleGoToDeclaration = (e) => { - if (!atomUtils.commandForTypeScript(e)) return; - - 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) => { - atom.workspace.open(definition.filePath, { - initialLine: definition.position.line, - initialColumn: definition.position.col - }); - } - }) - } - else { - var definition = definitions[0]; - - atom.workspace.open(definition.filePath, { - initialLine: definition.position.line, - initialColumn: definition.position.col - }); - } - }); - }; - - 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: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}`); - } - }); - }); + // 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:go-to-declaration', (e) => { + // if (!atomUtils.commandForTypeScript(e)) return; + + // 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) => { + // atom.workspace.open(definition.filePath, { + // initialLine: definition.position.line, + // initialColumn: definition.position.col + // }); + // } + // }) + // } + // else { + // var definition = definitions[0]; + + // atom.workspace.open(definition.filePath, { + // initialLine: definition.position.line, + // initialColumn: definition.position.col + // }); + // } + // }); + // }); + + // 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) => { @@ -126,62 +109,59 @@ export function registerCommands() { autoCompleteProvider.triggerAutocompletePlus(); }); - atom.commands.add('atom-text-editor', 'typescript:rename-refactor', (e) => { - // Rename file - var editor = atom.workspace.getActiveTextEditor(); - - // Rename variable - if (true) { - 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-text-editor', 'typescript:rename-refactor', (e) => { + // // Rename variable + // if (true) { + // 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(); @@ -227,127 +207,68 @@ export function registerCommands() { 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 - }); - } - }) - }); - }); + // 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(); + // 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(); - }); + // parent.getNavigationBarItems({ filePath }).then((res) => { + // theFileSymbolsView.setNavBarItems(res.items, filePath); + // theFileSymbolsView.show(); + // }); - }, 400); + // }, 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); - }); + // atom.commands.add('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('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); - } - }); + // 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('atom-workspace', 'typescript:sync', (e) => { if (!atomUtils.commandForTypeScript(e)) return; 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/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 index ca3ee7e40..5faf62344 100644 --- a/lib/main/atom/fileStatusCache.ts +++ b/lib/main/atom/fileStatusCache.ts @@ -2,7 +2,6 @@ * 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 { diff --git a/lib/main/atom/onSaveHandler.ts b/lib/main/atom/onSaveHandler.ts deleted file mode 100644 index fa993a4dd..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 TODO: Restore this functionality - // 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 0a87d316a..ab827f741 100644 --- a/lib/main/atom/tooltipManager.ts +++ b/lib/main/atom/tooltipManager.ts @@ -1,8 +1,6 @@ // 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 @@ -134,7 +132,3 @@ function pixelPositionFromMouseEvent(editorView, event: MouseEvent) { 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/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/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/fileSymbolsView.ts b/lib/main/atom/views/fileSymbolsView.ts index 7e8d73815..585fe292f 100644 --- a/lib/main/atom/views/fileSymbolsView.ts +++ b/lib/main/atom/views/fileSymbolsView.ts @@ -1,9 +1,7 @@ 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 { @@ -32,7 +30,7 @@ export class FileSymbolsView extends sp.SelectListView { `; } - + /** override */ confirmed(item: NavigationBarItem) { atom.workspace.open(this.filePath, { diff --git a/lib/main/atom/views/lineMessageView.ts b/lib/main/atom/views/lineMessageView.ts index de64bb9e1..0a1692a1c 100644 --- a/lib/main/atom/views/lineMessageView.ts +++ b/lib/main/atom/views/lineMessageView.ts @@ -1,6 +1,5 @@ import view = require('./view'); var $ = view.$; -import path = require('path'); export interface ViewOptions { /** This is needed to support good goto next / goto previous logic diff --git a/lib/main/atom/views/mainPanelView.ts b/lib/main/atom/views/mainPanelView.ts index 2cc8f77d2..d66a229ae 100644 --- a/lib/main/atom/views/mainPanelView.ts +++ b/lib/main/atom/views/mainPanelView.ts @@ -1,11 +1,8 @@ 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', @@ -18,11 +15,7 @@ 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; @@ -385,7 +378,6 @@ export class MainPanelView extends view.View { 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); diff --git a/lib/main/atom/views/plainMessageView.ts b/lib/main/atom/views/plainMessageView.ts index 544b7d7e8..8bcf7879a 100644 --- a/lib/main/atom/views/plainMessageView.ts +++ b/lib/main/atom/views/plainMessageView.ts @@ -1,6 +1,4 @@ import view = require('./view'); -var $ = view.$; -import path = require('path'); export interface ViewOptions { /** your message to the people */ diff --git a/lib/main/atom/views/projectSymbolsView.ts b/lib/main/atom/views/projectSymbolsView.ts index ce43e199f..6b78c4f5e 100644 --- a/lib/main/atom/views/projectSymbolsView.ts +++ b/lib/main/atom/views/projectSymbolsView.ts @@ -1,8 +1,6 @@ import sp = require('atom-space-pen-views'); -import mainPanelView = require('./mainPanelView'); import atomUtils = require("../atomUtils"); - /** * https://github.com/atom/atom-space-pen-views */ diff --git a/lib/main/atom/views/simpleOverlaySelectionView.ts b/lib/main/atom/views/simpleOverlaySelectionView.ts index 8de3491a4..c78503639 100644 --- a/lib/main/atom/views/simpleOverlaySelectionView.ts +++ b/lib/main/atom/views/simpleOverlaySelectionView.ts @@ -32,7 +32,6 @@ export default function (options: SelectListViewOptions, editor: AtomCore. */ import sp = require('atom-space-pen-views'); -import * as atomUtils from "../atomUtils"; export class SimpleOverlaySelectListView extends sp.SelectListView { diff --git a/lib/main/atom/views/simpleSelectionView.ts b/lib/main/atom/views/simpleSelectionView.ts index f1538bbab..765ea2ab6 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); @@ -76,7 +75,7 @@ export class SimpleSelectListView extends sp.SelectListView { 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() { diff --git a/lib/main/atomts.ts b/lib/main/atomts.ts index 944381565..d2b31ac71 100644 --- a/lib/main/atomts.ts +++ b/lib/main/atomts.ts @@ -2,44 +2,24 @@ console.log("be initializing them package") console.profile("atomts init") const start = process.hrtime() -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 _atom = require('atom') +import {$} from "atom-space-pen-views" +import {errorView} from "./atom/views/mainPanelView" +import {getFileStatus} from "./atom/fileStatusCache" import * as _ from "lodash" - -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 {getFileStatus} from "./atom/fileStatusCache"; - -import editorSetup = require("./atom/editorSetup"); +import * as hyperclickProvider from "../hyperclickProvider" +import atomConfig = require('./atom/atomConfig') +import atomUtils = require('./atom/atomUtils') +import autoCompleteProvider = require('./atom/autoCompleteProvider') +import commands = require("./atom/commands/commands") +import documentationView = require('./atom/views/documentationView') +import fs = require('fs') +import mainPanelView = require("./atom/views/mainPanelView") +import path = require('path') +import renameView = require('./atom/views/renameView') +import tooltipManager = require('./atom/tooltipManager') // globals -var statusBar; var statusBarMessage; var editorWatch: AtomCore.Disposable; var autoCompleteWatch: AtomCore.Disposable; @@ -150,7 +130,6 @@ function readyToActivate() { }) - let isTst = ext === '.tst'; try { // Only once stuff attachViews() @@ -171,8 +150,6 @@ function readyToActivate() { // Setup the TS reporter: hideIfNotActiveOnStart(); - debugAtomTs.runDebugCode({ filePath, editor }); - if (onDisk) { client.executeGetErr({files: [filePath], delay: 100}) @@ -195,9 +172,6 @@ function readyToActivate() { // }); } - // Setup additional observers on the editor - editorSetup.setupEditor(editor); - // Observe editors changing var changeObserver = editor.onDidStopChanging(() => { @@ -232,7 +206,6 @@ function readyToActivate() { }); - var buffer = editor.buffer; var fasterChangeObserver: AtomCore.Disposable = (editor.buffer).onDidChange((diff: { oldRange: TextBuffer.IRange; newRange: TextBuffer.IRange; oldText: string; newText: string }) => { //// For debugging @@ -327,25 +300,19 @@ export function activate(state: PackageState) { }) }) - // require('atom-package-deps').install('atom-typescript').then(readyToActivate) + require('atom-package-deps').install('atom-typescript').then(readyToActivate) } export function deactivate() { if (statusBarMessage) statusBarMessage.destroy(); if (editorWatch) editorWatch.dispose(); if (autoCompleteWatch) autoCompleteWatch.dispose(); - - parent.stopWorker(); } export function serialize(): PackageState { return {}; } -export function deserialize() { - /* do any tear down here */ -} - export function consumeLinter(registry: LinterRegistry) { console.log("consume this") @@ -361,7 +328,6 @@ export function provide() { return [autoCompleteProvider.provider]; } -import * as hyperclickProvider from "../hyperclickProvider"; export function getHyperclickProvider() { return hyperclickProvider; } 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 4e2b22877..000000000 --- a/lib/main/lang/core/languageServiceHost2.ts +++ /dev/null @@ -1,392 +0,0 @@ -import fs = require('fs'); -import os = require('os') -import path = require('path'); -import textBuffer = require('basarat-text-buffer'); -import utils = require('../utils'); - -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]] as any, newText, 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] as any); - } - - /** - * 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(fs.existsSync(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; -} 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/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 d81ec89f6..000000000 --- a/lib/main/lang/fixmyts/quickFixRegistry.ts +++ /dev/null @@ -1,34 +0,0 @@ -import {QuickFix} from "./quickFix"; -/** - * This exists to register the quick fixes - */ -import {AddClassMember} from "./quickFixes/addClassMember"; -import {AddClassMethod} from "./quickFixes/addClassMethod"; -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 AddImportFromStatement(), - new AddImportStatement(), - new WrapInProperty(), - new EqualsToEquals(), - new ExtractVariable(), - new StringConcatToTemplate(), - new QuotesToQuotes(), - new QuoteToTemplate(), - new TypeAssertPropertyAccessToAny(), - new TypeAssertPropertyAccessToType(), - new ImplementInterface(), - new SingleLineCommentToJsdoc() -]; 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/addImportFromStatement.ts b/lib/main/lang/fixmyts/quickFixes/addImportFromStatement.ts deleted file mode 100644 index b9ce35671..000000000 --- a/lib/main/lang/fixmyts/quickFixes/addImportFromStatement.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 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 d707e5040..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/building.ts b/lib/main/lang/modules/building.ts deleted file mode 100644 index ad4708019..000000000 --- a/lib/main/lang/modules/building.ts +++ /dev/null @@ -1,106 +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'); - -/** 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 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 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 c44803f75..000000000 --- a/lib/main/lang/modules/getPathCompletions.ts +++ /dev/null @@ -1,78 +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; -} - -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: 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; -} 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 cd3f747f0..000000000 --- a/lib/main/lang/projectService.ts +++ /dev/null @@ -1,887 +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 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; -} - -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 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 }); -} - -/** - * Reset all that we know about the file system - */ -export function softReset(query: SoftResetQuery): Promise<{}> { - console.log("Resetting..") - 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/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/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 78b3a28e2..000000000 --- a/lib/main/tsconfig/tsconfig.ts +++ /dev/null @@ -1,908 +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'] }, - 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 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/tsconfig.json b/lib/tsconfig.json index fac28fae8..38f85302a 100644 --- a/lib/tsconfig.json +++ b/lib/tsconfig.json @@ -8,6 +8,7 @@ "importHelpers": true, "removeComments": true, "noLib": false, + "noUnusedLocals": true, "preserveConstEnums": true, "outDir": "../dist", "sourceMap": false, 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/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/lib/workerLib.ts b/lib/worker/lib/workerLib.ts deleted file mode 100644 index 452cabd0f..000000000 --- a/lib/worker/lib/workerLib.ts +++ /dev/null @@ -1,346 +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]: any } } = {}; - - /** Only relevant when we only want the last of this type */ - private currentLastOfType: { - [message: string]: { data: any, defer: any } - } = {}; - - 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 - - console.log("received", parsed.message, "with", parsed.data) - - 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) => { - - console.log("sending", message, "with", data) - - // 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; - - console.log("received", message, "with", parsed.data) - - 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 index b112b6301..94a689888 100644 --- a/lib/worker/parent.ts +++ b/lib/worker/parent.ts @@ -1,98 +1,6 @@ -import {debugSync} from "./debug"; - -import * as path from "path" -import * as tsconfig from "tsconfig/dist/tsconfig" - -import workerLib = require('./lib/workerLib'); -import * as protocol from "typescript/lib/protocol"; -import * as atomConfig from "../main/atom/atomConfig"; - -import {TypescriptServiceClient} from "../client/client" import {ClientResolver} from "../client/clientResolver" - -var parent = new workerLib.Parent(); -import * as mainPanel from "../main/atom/views/mainPanelView"; - -/** 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 getCompletionsAtPosition = parent.sendToIpcOnlyLast(projectService.getCompletionsAtPosition, { - completions: [], - endsInPunctuation: false -}); -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 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 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 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); +import * as mainPanel from "../main/atom/views/mainPanelView" +import * as tsconfig from "tsconfig/dist/tsconfig" export const clients = new ClientResolver() 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 { } From cafe364d848f40b9a4ee5e52a540ddef8964b9b7 Mon Sep 17 00:00:00 2001 From: Guntars Asmanis-Graham Date: Wed, 30 Nov 2016 23:37:27 -0500 Subject: [PATCH 16/70] Trim down the dependencies and more --- VSProj.njsproj | 96 - VSProj.sln | 22 - dist/hyperclickProvider.js | 3 +- dist/main/atom/buildView.js | 47 - dist/main/atom/commands/json2dtsCommands.js | 14 - dist/main/atom/debugAtomTs.js | 7 - dist/main/atom/editorSetup.js | 4 - dist/main/atom/onSaveHandler.js | 4 - dist/main/atom/signatureProvider.js | 4 - dist/main/atom/typescriptGrammar.js | 228 -- dist/main/atom/views/astView.js | 154 - dist/main/atom/views/awesomePanelView.js | 24 - dist/main/atom/views/dependencyView.js | 397 -- dist/main/atom/views/semanticView.js | 153 - dist/main/atomts.js | 6 +- dist/main/json2dts/json2dts.js | 22 - dist/main/lang/core/languageServiceHost2.js | 274 -- dist/main/lang/core/project.js | 38 - dist/main/lang/fixmyts/quickFix.js | 18 - dist/main/lang/fixmyts/quickFixRegistry.js | 31 - .../lang/fixmyts/quickFixes/addClassMember.js | 88 - .../lang/fixmyts/quickFixes/addClassMethod.js | 154 - .../quickFixes/addImportFromStatement.js | 58 - .../fixmyts/quickFixes/addImportStatement.js | 58 - .../lang/fixmyts/quickFixes/equalsToEquals.js | 33 - .../fixmyts/quickFixes/extractVariable.js | 179 - .../fixmyts/quickFixes/implementInterface.js | 47 - .../fixmyts/quickFixes/quoteToTemplate.js | 34 - .../lang/fixmyts/quickFixes/quotesToQuotes.js | 39 - .../quickFixes/singleLineCommentToJsdoc.js | 44 - .../quickFixes/stringConcatToTemplate.js | 89 - .../typeAssertPropertyAccessToAny.js | 48 - .../typeAssertPropertyAccessToType.js | 49 - .../lang/fixmyts/quickFixes/wrapInProperty.js | 78 - dist/main/lang/modules/building.js | 77 - dist/main/lang/modules/formatting.js | 27 - dist/main/lang/modules/getPathCompletions.js | 46 - dist/main/lang/modules/moveFiles.js | 39 - dist/main/lang/modules/programDependencies.js | 36 - dist/main/lang/projectCache.js | 164 - dist/main/lang/projectService.js | 307 -- .../implementations/nullTransformer.js | 13 - dist/main/lang/transformers/transformer.js | 39 - .../lang/transformers/transformerRegistry.js | 37 - dist/main/lang/typescriptServices.js | 6 - dist/main/react/htmltotsx.js | 9 - dist/main/tsconfig/dts-generator.js | 172 - dist/main/tsconfig/formatting.js | 84 +- dist/main/tsconfig/simpleValidator.js | 65 - dist/main/tsconfig/tsconfig.js | 584 --- dist/typescript/makeTypeScriptGlobal.js | 18 - dist/worker/child.js | 15 - dist/worker/lib/workerLib.js | 244 -- dist/worker/queryParent.js | 98 - globals.js | 0 lib/globals.ts | 45 - lib/hyperclickProvider.ts | 7 +- lib/main/atomts.ts | 7 +- lib/main/lang/fixmyts/astUtils.ts | 117 - lib/main/lang/modules/astToText.ts | 398 -- lib/main/react/htmltotsx.ts | 13 - lib/main/tsconfig/formatting.ts | 111 +- lib/tsconfig.json | 4 +- lib/tsd.json | 42 - lib/typings/bluebird.d.ts | 142 - lib/typings/brackets.d.ts | 1172 ------ lib/typings/codemirror.d.ts | 849 ---- lib/typings/d3/d3.d.ts | 3459 ----------------- lib/typings/emissary/emissary.d.ts | 59 - lib/typings/htmltojsx/htmltojsx.d.ts | 17 - lib/typings/minimatch/minimatch.d.ts | 64 - lib/typings/mkdirp/mkdirp.d.ts | 15 - lib/typings/mustache.d.ts | 11 - lib/typings/q/Q.d.ts | 317 -- lib/typings/tsd.d.ts | 5 - lib/worker/debug.ts | 5 - package.json | 22 +- pull_request_template.md | 2 +- styles/ast-view.less | 25 - styles/atomts-file-semantic-view.less | 115 - styles/atomts-r-view.less | 3 - styles/dependency-view.less | 136 - styles/semantic-view.less | 109 - typings.json | 9 - views/views.d.ts | 10 - 85 files changed, 53 insertions(+), 11861 deletions(-) delete mode 100644 VSProj.njsproj delete mode 100644 VSProj.sln delete mode 100644 dist/main/atom/buildView.js delete mode 100644 dist/main/atom/commands/json2dtsCommands.js delete mode 100644 dist/main/atom/debugAtomTs.js delete mode 100644 dist/main/atom/editorSetup.js delete mode 100644 dist/main/atom/onSaveHandler.js delete mode 100644 dist/main/atom/signatureProvider.js delete mode 100644 dist/main/atom/typescriptGrammar.js delete mode 100644 dist/main/atom/views/astView.js delete mode 100644 dist/main/atom/views/awesomePanelView.js delete mode 100644 dist/main/atom/views/dependencyView.js delete mode 100644 dist/main/atom/views/semanticView.js delete mode 100644 dist/main/json2dts/json2dts.js delete mode 100644 dist/main/lang/core/languageServiceHost2.js delete mode 100644 dist/main/lang/core/project.js delete mode 100644 dist/main/lang/fixmyts/quickFix.js delete mode 100644 dist/main/lang/fixmyts/quickFixRegistry.js delete mode 100644 dist/main/lang/fixmyts/quickFixes/addClassMember.js delete mode 100644 dist/main/lang/fixmyts/quickFixes/addClassMethod.js delete mode 100644 dist/main/lang/fixmyts/quickFixes/addImportFromStatement.js delete mode 100644 dist/main/lang/fixmyts/quickFixes/addImportStatement.js delete mode 100644 dist/main/lang/fixmyts/quickFixes/equalsToEquals.js delete mode 100644 dist/main/lang/fixmyts/quickFixes/extractVariable.js delete mode 100644 dist/main/lang/fixmyts/quickFixes/implementInterface.js delete mode 100644 dist/main/lang/fixmyts/quickFixes/quoteToTemplate.js delete mode 100644 dist/main/lang/fixmyts/quickFixes/quotesToQuotes.js delete mode 100644 dist/main/lang/fixmyts/quickFixes/singleLineCommentToJsdoc.js delete mode 100644 dist/main/lang/fixmyts/quickFixes/stringConcatToTemplate.js delete mode 100644 dist/main/lang/fixmyts/quickFixes/typeAssertPropertyAccessToAny.js delete mode 100644 dist/main/lang/fixmyts/quickFixes/typeAssertPropertyAccessToType.js delete mode 100644 dist/main/lang/fixmyts/quickFixes/wrapInProperty.js delete mode 100644 dist/main/lang/modules/building.js delete mode 100644 dist/main/lang/modules/formatting.js delete mode 100644 dist/main/lang/modules/getPathCompletions.js delete mode 100644 dist/main/lang/modules/moveFiles.js delete mode 100644 dist/main/lang/modules/programDependencies.js delete mode 100644 dist/main/lang/projectCache.js delete mode 100644 dist/main/lang/projectService.js delete mode 100644 dist/main/lang/transformers/implementations/nullTransformer.js delete mode 100644 dist/main/lang/transformers/transformer.js delete mode 100644 dist/main/lang/transformers/transformerRegistry.js delete mode 100644 dist/main/lang/typescriptServices.js delete mode 100644 dist/main/react/htmltotsx.js delete mode 100644 dist/main/tsconfig/dts-generator.js delete mode 100644 dist/main/tsconfig/simpleValidator.js delete mode 100644 dist/main/tsconfig/tsconfig.js delete mode 100644 dist/typescript/makeTypeScriptGlobal.js delete mode 100644 dist/worker/child.js delete mode 100644 dist/worker/lib/workerLib.js delete mode 100644 dist/worker/queryParent.js delete mode 100644 globals.js delete mode 100644 lib/main/lang/fixmyts/astUtils.ts delete mode 100644 lib/main/lang/modules/astToText.ts delete mode 100644 lib/main/react/htmltotsx.ts delete mode 100644 lib/tsd.json delete mode 100644 lib/typings/bluebird.d.ts delete mode 100644 lib/typings/brackets.d.ts delete mode 100644 lib/typings/codemirror.d.ts delete mode 100644 lib/typings/d3/d3.d.ts delete mode 100644 lib/typings/emissary/emissary.d.ts delete mode 100644 lib/typings/htmltojsx/htmltojsx.d.ts delete mode 100644 lib/typings/minimatch/minimatch.d.ts delete mode 100644 lib/typings/mkdirp/mkdirp.d.ts delete mode 100644 lib/typings/mustache.d.ts delete mode 100644 lib/typings/q/Q.d.ts delete mode 100644 lib/typings/tsd.d.ts delete mode 100644 lib/worker/debug.ts delete mode 100644 styles/ast-view.less delete mode 100644 styles/atomts-file-semantic-view.less delete mode 100644 styles/atomts-r-view.less delete mode 100644 styles/dependency-view.less delete mode 100644 styles/semantic-view.less delete mode 100644 typings.json delete mode 100644 views/views.d.ts diff --git a/VSProj.njsproj b/VSProj.njsproj deleted file mode 100644 index 2eb8214f6..000000000 --- a/VSProj.njsproj +++ /dev/null @@ -1,96 +0,0 @@ - - - - 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/hyperclickProvider.js b/dist/hyperclickProvider.js index 796650bec..0424f3b4a 100644 --- a/dist/hyperclickProvider.js +++ b/dist/hyperclickProvider.js @@ -1,6 +1,5 @@ "use strict"; -var immutable_1 = require("immutable"); -var TS_GRAMMARS = immutable_1.Set(["source.ts", "source.tsx"]); +var TS_GRAMMARS = new Set(["source.ts", "source.tsx"]); exports.providerName = "typescript-hyperclick-provider"; exports.wordRegExp = /([A-Za-z0-9_])+|['"`](\\.|[^'"`\\\\])*['"`]/g; function getSuggestionForWord(textEditor, text, range) { 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/json2dtsCommands.js b/dist/main/atom/commands/json2dtsCommands.js deleted file mode 100644 index 7c2ede9bf..000000000 --- a/dist/main/atom/commands/json2dtsCommands.js +++ /dev/null @@ -1,14 +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 text = editor.getSelectedText(); - var range = editor.getSelectedBufferRange(); - editor.setTextInBufferRange(range, json2dts_1.convert(text)); - }); -} -exports.registerJson2dtsCommands = registerJson2dtsCommands; 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 deleted file mode 100644 index 9e755204d..000000000 --- a/dist/main/atom/editorSetup.js +++ /dev/null @@ -1,4 +0,0 @@ -"use strict"; -function setupEditor(editor) { -} -exports.setupEditor = setupEditor; diff --git a/dist/main/atom/onSaveHandler.js b/dist/main/atom/onSaveHandler.js deleted file mode 100644 index d2f131163..000000000 --- a/dist/main/atom/onSaveHandler.js +++ /dev/null @@ -1,4 +0,0 @@ -"use strict"; -function handle(event) { -} -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/typescriptGrammar.js b/dist/main/atom/typescriptGrammar.js deleted file mode 100644 index 2d23ca1df..000000000 --- a/dist/main/atom/typescriptGrammar.js +++ /dev/null @@ -1,228 +0,0 @@ -"use strict"; -var tslib_1 = require("tslib"); -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) { - tslib_1.__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/views/astView.js b/dist/main/atom/views/astView.js deleted file mode 100644 index 01033e3f2..000000000 --- a/dist/main/atom/views/astView.js +++ /dev/null @@ -1,154 +0,0 @@ -"use strict"; -var tslib_1 = require("tslib"); -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) { - tslib_1.__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 7b371883a..000000000 --- a/dist/main/atom/views/awesomePanelView.js +++ /dev/null @@ -1,24 +0,0 @@ -"use strict"; -var tslib_1 = require("tslib"); -var view = require("./view"); -var $ = view.$; -var AwesomePanelView = (function (_super) { - tslib_1.__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/dependencyView.js b/dist/main/atom/views/dependencyView.js deleted file mode 100644 index 8b09e64b7..000000000 --- a/dist/main/atom/views/dependencyView.js +++ /dev/null @@ -1,397 +0,0 @@ -"use strict"; -var tslib_1 = require("tslib"); -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) { - tslib_1.__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.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/semanticView.js b/dist/main/atom/views/semanticView.js deleted file mode 100644 index a9561bde5..000000000 --- a/dist/main/atom/views/semanticView.js +++ /dev/null @@ -1,153 +0,0 @@ -"use strict"; -var tslib_1 = require("tslib"); -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) { - tslib_1.__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) { - tslib_1.__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/atomts.js b/dist/main/atomts.js index fe6bb10c5..f49a17ba2 100644 --- a/dist/main/atomts.js +++ b/dist/main/atomts.js @@ -2,7 +2,7 @@ var tslib_1 = require("tslib"); console.log("be initializing them package"); console.profile("atomts init"); -var start = process.hrtime(); +var startTime = process.hrtime(); var _atom = require("atom"); var atom_space_pen_views_1 = require("atom-space-pen-views"); var mainPanelView_1 = require("./atom/views/mainPanelView"); @@ -80,7 +80,7 @@ function readyToActivate() { filePath: filePath, startPos: { line: error.start.line - 1, col: error.start.offset - 1 }, endPos: { line: error.end.line - 1, col: error.end.offset - 1 }, - message: ts.flattenDiagnosticMessageText(error.text, '\n'), + message: error.text, preview: preview }; })); @@ -205,4 +205,4 @@ function getHyperclickProvider() { } exports.getHyperclickProvider = getHyperclickProvider; console.profileEnd(); -console.log("init took", process.hrtime(start)); +console.log("init took", process.hrtime(startTime)); 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 789267d6a..000000000 --- a/dist/main/lang/core/languageServiceHost2.js +++ /dev/null @@ -1,274 +0,0 @@ -"use strict"; -var fs = require("fs"); -var os = require("os"); -var path = require("path"); -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, 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 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 (fs.existsSync(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; - 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/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 ab1c36edb..000000000 --- a/dist/main/lang/fixmyts/quickFixRegistry.js +++ /dev/null @@ -1,31 +0,0 @@ -"use strict"; -var addClassMember_1 = require("./quickFixes/addClassMember"); -var addClassMethod_1 = require("./quickFixes/addClassMethod"); -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 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/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/building.js b/dist/main/lang/modules/building.js deleted file mode 100644 index fef9804b1..000000000 --- a/dist/main/lang/modules/building.js +++ /dev/null @@ -1,77 +0,0 @@ -"use strict"; -var path = require("path"); -var fsUtil_1 = require("../../utils/fsUtil"); -var findup = require('findup'); -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 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 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 0402a8991..000000000 --- a/dist/main/lang/modules/getPathCompletions.js +++ /dev/null @@ -1,46 +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 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: 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 deleted file mode 100644 index 0904e2d53..000000000 --- a/dist/main/lang/projectService.js +++ /dev/null @@ -1,307 +0,0 @@ -"use strict"; -var path = require("path"); -var tsconfig = require("../tsconfig/tsconfig"); -var resolve = Promise.resolve.bind(Promise); -var projectCache_1 = require("./projectCache"); -function textSpan(span) { - return { - start: span.start, - length: span.length - }; -} -function echo(data) { - return projectCache_1.queryParent.echoNumWithModification({ num: data.num }).then(function (resp) { - data.num = resp.num; - return data; - }); -} -exports.echo = echo; -function quickInfo(query) { - projectCache_1.consistentPath(query); - var project = projectCache_1.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 || []) - }); - } -} -exports.quickInfo = quickInfo; -function getSignatureHelps(query) { - projectCache_1.consistentPath(query); - var project = projectCache_1.getOrCreateProject(query.filePath); - var signatureHelpItems = project.languageService.getSignatureHelpItems(query.filePath, query.position); - if (!signatureHelpItems || !signatureHelpItems.items || !signatureHelpItems.items.length) - return resolve({ signatureHelps: [] }); - return signatureHelpItems.items; -} -exports.getSignatureHelps = getSignatureHelps; -var formatting = require("./modules/formatting"); -function formatDocument(query) { - projectCache_1.consistentPath(query); - var proj = projectCache_1.getOrCreateProject(query.filePath); - return resolve({ edits: formatting.formatDocument(proj, query.filePath) }); -} -exports.formatDocument = formatDocument; -function formatDocumentRange(query) { - projectCache_1.consistentPath(query); - var proj = projectCache_1.getOrCreateProject(query.filePath); - return resolve({ edits: formatting.formatDocumentRange(proj, query.filePath, query.start, query.end) }); -} -exports.formatDocumentRange = formatDocumentRange; -function getDefinitionsAtPosition(query) { - projectCache_1.consistentPath(query); - var project = projectCache_1.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(function (d) { - var pos = project.languageServiceHost.getPositionFromIndex(d.fileName, d.textSpan.start); - return { - filePath: d.fileName, - position: pos - }; - }) - }); -} -exports.getDefinitionsAtPosition = getDefinitionsAtPosition; -function getRenameInfo(query) { - projectCache_1.consistentPath(query); - var project = projectCache_1.getOrCreateProject(query.filePath); - var findInStrings = false, findInComments = false; - var info = project.languageService.getRenameInfo(query.filePath, query.position); - if (info && info.canRename) { - var locations = {}; - project.languageService.findRenameLocations(query.filePath, query.position, findInStrings, findInComments) - .forEach(function (loc) { - if (!locations[loc.fileName]) - locations[loc.fileName] = []; - 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 - }); - } -} -exports.getRenameInfo = getRenameInfo; -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 }); -} -exports.getIndentationAtPosition = getIndentationAtPosition; -function debugLanguageServiceHostVersion(query) { - projectCache_1.consistentPath(query); - var project = projectCache_1.getOrCreateProject(query.filePath); - return resolve({ text: project.languageServiceHost.getScriptContent(query.filePath) }); -} -exports.debugLanguageServiceHostVersion = debugLanguageServiceHostVersion; -function getProjectFileDetails(query) { - projectCache_1.consistentPath(query); - var project = projectCache_1.getOrCreateProject(query.filePath); - return resolve(project.projectFile); -} -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]; - if (item.childItems) { - sortNavbarItemsBySpan(item.childItems); - } - } -} -function flattenNavBarItems(items) { - var toreturn = []; - function keepAdding(item, depth) { - item.indent = depth; - var children = item.childItems; - delete item.childItems; - toreturn.push(item); - if (children) { - children.forEach(function (child) { return keepAdding(child, depth + 1); }); - } - } - items.forEach(function (item) { return keepAdding(item, 0); }); - return toreturn; -} -function getNavigationBarItems(query) { - projectCache_1.consistentPath(query); - var project = projectCache_1.getOrCreateProject(query.filePath); - var languageService = project.languageService; - var navBarItems = languageService.getNavigationBarItems(query.filePath); - if (navBarItems.length && navBarItems[0].text == "") { - navBarItems.shift(); - } - sortNavbarItemsBySpan(navBarItems); - navBarItems = flattenNavBarItems(navBarItems); - var items = navBarItems.map(function (item) { - item.position = project.languageServiceHost.getPositionFromIndex(query.filePath, item.spans[0].start); - delete item.spans; - return item; - }); - return resolve({ items: items }); -} -exports.getNavigationBarItems = getNavigationBarItems; -function navigationBarItemToSemanticTreeNode(item, project, query) { - var toReturn = { - 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(function (ci) { return navigationBarItemToSemanticTreeNode(ci, project, query); }) : [] - }; - return toReturn; -} -function getSemtanticTree(query) { - projectCache_1.consistentPath(query); - var project = projectCache_1.getOrCreateProject(query.filePath); - var navBarItems = project.languageService.getNavigationBarItems(query.filePath); - if (navBarItems.length && navBarItems[0].text == "") { - navBarItems.shift(); - } - sortNavbarItemsBySpan(navBarItems); - var nodes = navBarItems.map(function (nbi) { return navigationBarItemToSemanticTreeNode(nbi, project, query); }); - return resolve({ nodes: nodes }); -} -exports.getSemtanticTree = getSemtanticTree; -function getNavigateToItems(query) { - projectCache_1.consistentPath(query); - var project = projectCache_1.getOrCreateProject(query.filePath); - var getNodeKind = ts.getNodeKind; - function getDeclarationName(declaration) { - var result = getTextOfIdentifierOrLiteral(declaration.name); - if (result !== undefined) { - return result; - } - if (declaration.name.kind === ts.SyntaxKind.ComputedPropertyName) { - var expr = declaration.name.expression; - if (expr.kind === ts.SyntaxKind.PropertyAccessExpression) { - return expr.name.text; - } - return getTextOfIdentifierOrLiteral(expr); - } - return undefined; - } - function getTextOfIdentifierOrLiteral(node) { - if (node.kind === ts.SyntaxKind.Identifier || - node.kind === ts.SyntaxKind.StringLiteral || - node.kind === ts.SyntaxKind.NumericLiteral) { - return node.text; - } - 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 = { - 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: items }); -} -exports.getNavigateToItems = getNavigateToItems; -function getReferences(query) { - projectCache_1.consistentPath(query); - var project = projectCache_1.getOrCreateProject(query.filePath); - var languageService = project.languageService; - var references = []; - var refs = languageService.getReferencesAtPosition(query.filePath, query.position) || []; - references = refs.map(function (r) { - var res = project.languageServiceHost.getPositionFromTextSpanWithLinePreview(r.fileName, r.textSpan); - return { filePath: r.fileName, position: res.position, preview: res.preview }; - }); - return resolve({ - references: references - }); -} -exports.getReferences = getReferences; -var getPathCompletions_1 = require("./modules/getPathCompletions"); -function getRelativePathsInProject(query) { - projectCache_1.consistentPath(query); - var project = projectCache_1.getOrCreateProject(query.filePath); - return resolve(getPathCompletions_1.getPathCompletions({ - project: project, - filePath: query.filePath, - prefix: query.prefix, - includeExternalModules: query.includeExternalModules - })); -} -exports.getRelativePathsInProject = getRelativePathsInProject; -var 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; }); - if (!files.length) - resolve({}); - var sourceFile = files[0]; - var root = astToText_1.astToText(sourceFile); - return resolve({ root: 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; }); - if (!files.length) - resolve({}); - var sourceFile = files[0]; - var root = astToText_1.astToTextFull(sourceFile); - return resolve({ root: root }); -} -exports.getASTFull = getASTFull; -var 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 }); -} -exports.getDependencies = getDependencies; -function createProject(query) { - projectCache_1.consistentPath(query); - var projectFile = tsconfig.createProjectRootSync(query.filePath); - projectCache_1.queryParent.setConfigurationError({ projectFilePath: query.filePath, error: null }); - return resolve({ createdFilePath: projectFile.projectFilePath }); -} -exports.createProject = createProject; 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/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..29fa22f8e 100644 --- a/dist/main/tsconfig/formatting.js +++ b/dist/main/tsconfig/formatting.js @@ -1,72 +1,24 @@ "use strict"; -var os = require("os"); +var 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; 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 7c03f53ff..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'] }, - 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/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/lib/workerLib.js b/dist/worker/lib/workerLib.js deleted file mode 100644 index ee86259ff..000000000 --- a/dist/worker/lib/workerLib.js +++ /dev/null @@ -1,244 +0,0 @@ -"use strict"; -var tslib_1 = require("tslib"); -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) { - console.log("sending", message, "with", data); - 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; - console.log("received", message, "with", parsed.data); - 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 { - console.log("received", parsed.message, "with", parsed.data); - 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) { - tslib_1.__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) { - tslib_1.__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/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/globals.js b/globals.js deleted file mode 100644 index e69de29bb..000000000 diff --git a/lib/globals.ts b/lib/globals.ts index dda204e5b..41c756c6b 100644 --- a/lib/globals.ts +++ b/lib/globals.ts @@ -1,14 +1,3 @@ -/// -/// - -// From brackets plugin -/// -/// -/// -/// - -/// - /** Utility function to print stack trace from whereever */ declare function stack(); declare module NodeJS { @@ -146,37 +135,3 @@ interface ReferenceDetails { 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 index 537c3feca..a03be5282 100644 --- a/lib/hyperclickProvider.ts +++ b/lib/hyperclickProvider.ts @@ -1,11 +1,6 @@ -// 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"]); +const TS_GRAMMARS = new 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) { diff --git a/lib/main/atomts.ts b/lib/main/atomts.ts index d2b31ac71..ad5873a2f 100644 --- a/lib/main/atomts.ts +++ b/lib/main/atomts.ts @@ -1,6 +1,7 @@ console.log("be initializing them package") console.profile("atomts init") -const start = process.hrtime() + +const startTime = process.hrtime() import _atom = require('atom') import {$} from "atom-space-pen-views" @@ -120,7 +121,7 @@ function readyToActivate() { filePath: filePath, startPos: {line: error.start.line - 1, col: error.start.offset - 1}, endPos: {line: error.end.line - 1, col: error.end.offset - 1}, - message: ts.flattenDiagnosticMessageText(error.text, '\n'), + message: error.text, preview } @@ -333,4 +334,4 @@ export function getHyperclickProvider() { } console.profileEnd() -console.log("init took", process.hrtime(start)) +console.log("init took", process.hrtime(startTime)) 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/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/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/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/tsconfig.json b/lib/tsconfig.json index 38f85302a..7fe45d27f 100644 --- a/lib/tsconfig.json +++ b/lib/tsconfig.json @@ -13,9 +13,7 @@ "outDir": "../dist", "sourceMap": false, "jsx": "react", - "types": [ - "byots" - ] + "types": [] }, "dts": { "name": "atom-typescript" diff --git a/lib/tsd.json b/lib/tsd.json deleted file mode 100644 index 803fc88c9..000000000 --- a/lib/tsd.json +++ /dev/null @@ -1,42 +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" - }, - "minimatch/minimatch.d.ts": { - "commit": "66f88ec51858bb21bc375fa91a963c04bc09401e" - } - } -} 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 9e806b349..000000000 --- a/lib/typings/emissary/emissary.d.ts +++ /dev/null @@ -1,59 +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/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/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/tsd.d.ts b/lib/typings/tsd.d.ts deleted file mode 100644 index cb51874b4..000000000 --- a/lib/typings/tsd.d.ts +++ /dev/null @@ -1,5 +0,0 @@ -/// -/// -/// -/// -/// diff --git a/lib/worker/debug.ts b/lib/worker/debug.ts deleted file mode 100644 index cb522f8e6..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 = true; - -/** Set this to true to run the child code in the UI thread and just debug using the dev tools */ -export var debugSync = false; diff --git a/package.json b/package.json index 2e3fd6b15..97d82568f 100644 --- a/package.json +++ b/package.json @@ -4,13 +4,10 @@ "main": "./dist/main/atomts", "preferGlobal": true, "description": "The only TypeScript plugin you will ever need.", - "activationHooks": [ - "atom-typescript:grammar-used" - ], + "activationHooks": ["atom-typescript:grammar-used"], "scripts": { "build": "ts-node scripts/grammar.ts", - "test": "tsc -p ./lib && tsc --noEmit -p ./scripts", - "prepublish": "typings install" + "test": "tsc -p ./lib && tsc --noEmit -p ./scripts" }, "engines": { "atom": ">=0.199.0 <2.0.0", @@ -29,11 +26,6 @@ "2.0.0": "provide" } }, - "linter": { - "versions": { - "1.0.0": "provideLinter" - } - }, "hyperclick.provider": { "versions": { "0.0.0": "getHyperclickProvider" @@ -58,21 +50,14 @@ "basarat-text-buffer": "6.0.0", "byline": "^5.0.0", "byots": "2.2.0-dev.20161129.23.20", - "d3": "^3.5.5", "detect-indent": "^4.0.0", "detect-newline": "^2.1.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", "lodash": "4.17.2", - "mkdirp": "^0.5.0", "resolve": "1.1.7", - "season": "^5.1.4", "tsconfig": "^2.2.0", "tslib": "1.2.0", "typescript": "2.2.0-dev.20161130" @@ -83,8 +68,7 @@ "mz": "^2.1.0", "plist": "2.0.1", "popsicle": "8.2.0", - "ts-node": "1.7.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/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-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/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/typings.json b/typings.json deleted file mode 100644 index 79cdcf0f0..000000000 --- a/typings.json +++ /dev/null @@ -1,9 +0,0 @@ -{ - "dependencies": { - "source-map": "github:typings/typed-source-map#86c25e7a550d5af7a63d979625602c17cce157f6", - "tsconfig": "npm:tsconfig" - }, - "ambientDependencies": { - "pathwatcher": "github:DefinitelyTyped/DefinitelyTyped/pathwatcher/pathwatcher.d.ts#aee42d3e873a332bda7ff2a77d0c5973a11cd2d3" - } -} 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(); -} From ae981eeac223dcb35d97b8e8a9fb639cf2e01b32 Mon Sep 17 00:00:00 2001 From: Guntars Asmanis-Graham Date: Fri, 2 Dec 2016 22:59:56 -0500 Subject: [PATCH 17/70] Use ES6, use push style linter --- dist/client/client.js | 161 +++++---- dist/client/clientResolver.js | 64 ++-- dist/client/findServer.js | 39 ++- dist/globals.js | 0 dist/hyperclickProvider.js | 4 +- dist/linter.js | 1 - dist/main/atom/atomConfig.js | 41 +-- dist/main/atom/atomUtils.js | 43 ++- dist/main/atom/autoCompleteProvider.js | 86 +++-- dist/main/atom/commands/commands.js | 37 +- dist/main/atom/components/ts-view.js | 18 +- dist/main/atom/fileStatusCache.js | 4 +- dist/main/atom/gotoHistory.js | 4 +- dist/main/atom/tooltipManager.js | 43 ++- dist/main/atom/views/contextView.js | 56 ++- dist/main/atom/views/documentationView.js | 62 ---- dist/main/atom/views/fileSymbolsView.js | 66 ++-- dist/main/atom/views/lineMessageView.js | 37 +- dist/main/atom/views/mainPanelView.js | 319 +++++++----------- dist/main/atom/views/plainMessageView.js | 24 +- dist/main/atom/views/projectSymbolsView.js | 84 +++-- dist/main/atom/views/renameView.js | 65 ++-- .../atom/views/simpleOverlaySelectionView.js | 69 ++-- dist/main/atom/views/simpleSelectionView.js | 62 ++-- dist/main/atom/views/tooltipView.js | 39 +-- dist/main/atom/views/typeOverlayView.js | 15 +- dist/main/atom/views/view.js | 65 ++-- dist/main/atomts.js | 293 ++++++++-------- dist/main/error_pusher.js | 38 +++ dist/main/lang/fixmyts/astUtils.js | 95 ------ dist/main/lang/modules/astToText.js | 69 ---- dist/main/lang/utils.js | 82 ++--- dist/main/tsconfig/formatting.js | 2 +- dist/main/utils/fsUtil.js | 10 +- dist/main/utils/tsUtil.js | 14 + dist/worker/debug.js | 3 - dist/worker/parent.js | 20 -- lib/client/client.ts | 4 + lib/client/clientResolver.ts | 30 ++ lib/main/atom/autoCompleteProvider.ts | 6 +- lib/main/atom/commands/commands.ts | 4 +- lib/main/atom/tooltipManager.ts | 11 +- lib/main/atom/views/documentationView.ts | 78 ----- lib/main/atom/views/mainPanelView.ts | 67 ---- lib/main/atomts.ts | 180 ++++------ lib/main/error_pusher.ts | 57 ++++ lib/main/utils/tsUtil.ts | 14 + lib/tsconfig.json | 5 +- lib/{linter.ts => typings/linter.d.ts} | 4 +- lib/{globals.ts => typings/typings.d.ts} | 0 lib/worker/parent.ts | 23 -- package.json | 5 +- styles/atomts-grammar-syntax.less | 2 +- styles/documentationview.less | 78 ----- ...tter.atom-text-editor.less => gutter.less} | 0 tslint.json | 1 + 56 files changed, 1070 insertions(+), 1633 deletions(-) delete mode 100644 dist/globals.js delete mode 100644 dist/linter.js delete mode 100644 dist/main/atom/views/documentationView.js create mode 100644 dist/main/error_pusher.js delete mode 100644 dist/main/lang/fixmyts/astUtils.js delete mode 100644 dist/main/lang/modules/astToText.js create mode 100644 dist/main/utils/tsUtil.js delete mode 100644 dist/worker/debug.js delete mode 100644 dist/worker/parent.js delete mode 100644 lib/main/atom/views/documentationView.ts create mode 100644 lib/main/error_pusher.ts create mode 100644 lib/main/utils/tsUtil.ts rename lib/{linter.ts => typings/linter.d.ts} (90%) rename lib/{globals.ts => typings/typings.d.ts} (100%) delete mode 100644 lib/worker/parent.ts delete mode 100644 styles/documentationview.less rename styles/{gutter.atom-text-editor.less => gutter.less} (100%) create mode 100644 tslint.json diff --git a/dist/client/client.js b/dist/client/client.js index 25fbb6e21..3c3243914 100644 --- a/dist/client/client.js +++ b/dist/client/client.js @@ -1,146 +1,142 @@ "use strict"; -var tslib_1 = require("tslib"); -var child_process_1 = require("child_process"); -var stream_1 = require("stream"); -var byline = require("byline"); -var TypescriptServiceClient = (function () { - function TypescriptServiceClient(tsServerPath) { - var _this = this; +const tslib_1 = require("tslib"); +const child_process_1 = require("child_process"); +const stream_1 = require("stream"); +const byline = require("byline"); +class TypescriptServiceClient { + constructor(tsServerPath) { this.callbacks = {}; this.listeners = {}; this.seq = 0; - this.onMessage = function (res) { + this.onMessage = (res) => { if (isResponse(res)) { - var callback = _this.callbacks[res.request_seq]; + const callback = this.callbacks[res.request_seq]; if (callback) { console.log("received response for", res.command, "in", Date.now() - callback.started, "ms", "with data", res.body); - delete _this.callbacks[res.request_seq]; + delete this.callbacks[res.request_seq]; if (res.success) { callback.resolve(res); } else { callback.reject(new Error(res.message)); } - _this.emitPendingRequests(); + this.emitPendingRequests(); } } else if (isEvent(res)) { console.log("received event", res); - _this.emit(res.event, res.body); + this.emit(res.event, res.body); } }; this.tsServerPath = tsServerPath; } - TypescriptServiceClient.prototype.executeChange = function (args) { + executeChange(args) { this.execute("change", args); - }; - TypescriptServiceClient.prototype.executeClose = function (args) { + } + executeClose(args) { this.execute("close", args); - }; - TypescriptServiceClient.prototype.executeCompletions = function (args) { + } + executeCompletions(args) { return this.execute("completions", args); - }; - TypescriptServiceClient.prototype.executeGetErr = function (args) { + } + executeGetErr(args) { this.execute("geterr", args); - }; - TypescriptServiceClient.prototype.executeOpen = function (args) { + } + executeGetErrForProject(args) { + this.execute("geterrForProject", args); + } + executeOpen(args) { this.execute("open", args); - }; - TypescriptServiceClient.prototype.executeProjectInfo = function (args) { + } + executeProjectInfo(args) { return this.execute("projectInfo", args); - }; - TypescriptServiceClient.prototype.executeQuickInfo = function (args) { + } + executeQuickInfo(args) { return this.execute("quickinfo", args); - }; - TypescriptServiceClient.prototype.execute = function (command, args) { - var _this = this; - return this.serverPromise.then(function (cp) { - var expectResponse = !!TypescriptServiceClient.commandWithResponse[command]; - return _this.sendRequest(cp, command, args, expectResponse); - }).catch(function (err) { + } + execute(command, args) { + return this.serverPromise.then(cp => { + const expectResponse = !!TypescriptServiceClient.commandWithResponse[command]; + return this.sendRequest(cp, command, args, expectResponse); + }).catch(err => { console.log("command", command, "failed due to", err); throw err; }); - }; - TypescriptServiceClient.prototype.on = function (name, listener) { - var _this = this; + } + on(name, listener) { if (this.listeners[name] === undefined) { this.listeners[name] = []; } this.listeners[name].push(listener); - return function () { - var idx = _this.listeners[name].indexOf(listener); - _this.listeners[name].splice(idx, 1); + return () => { + const idx = this.listeners[name].indexOf(listener); + this.listeners[name].splice(idx, 1); }; - }; - TypescriptServiceClient.prototype.emit = function (name, data) { - var listeners = this.listeners[name]; + } + emit(name, data) { + const listeners = this.listeners[name]; if (listeners) { - for (var _i = 0, listeners_1 = listeners; _i < listeners_1.length; _i++) { - var listener = listeners_1[_i]; + for (const listener of listeners) { listener(data); } } - }; - TypescriptServiceClient.prototype.emitPendingRequests = function () { - var pending = []; - for (var callback in this.callbacks) { + } + emitPendingRequests() { + const pending = []; + for (const callback in this.callbacks) { pending.push(this.callbacks[callback].name); } this.emit("pendingRequestsChange", pending); - }; - TypescriptServiceClient.prototype.sendRequest = function (cp, command, args, expectResponse) { - var _this = this; - var req = { + } + sendRequest(cp, command, args, expectResponse) { + const req = { seq: this.seq++, - command: command, + command, arguments: args }; console.log("sending request", command, "with args", args); - var resultPromise = undefined; + let resultPromise = undefined; if (expectResponse) { - resultPromise = new Promise(function (resolve, reject) { - _this.callbacks[req.seq] = { name: command, resolve: resolve, reject: reject, started: Date.now() }; + resultPromise = new Promise((resolve, reject) => { + this.callbacks[req.seq] = { name: command, resolve, reject, started: Date.now() }; }); this.emitPendingRequests(); } cp.stdin.write(JSON.stringify(req) + "\n"); return resultPromise; - }; - TypescriptServiceClient.prototype.startServer = function () { - var _this = this; + } + startServer() { if (!this.serverPromise) { - this.serverPromise = new Promise(function (resolve, reject) { - console.log("starting", _this.tsServerPath); - var cp = child_process_1.spawn(_this.tsServerPath, []); - cp.once("error", function (err) { + this.serverPromise = new Promise((resolve, reject) => { + console.log("starting", this.tsServerPath); + const cp = child_process_1.spawn(this.tsServerPath, []); + cp.once("error", err => { console.log("tsserver starting failed with", err); reject(err); }); - cp.once("exit", function (code) { + cp.once("exit", code => { console.log("tsserver failed to start with code", code); - reject({ code: code }); + reject({ code }); }); - messageStream(cp.stdout).on("data", _this.onMessage); - _this.sendRequest(cp, "ping", null, true).then(function (res) { return resolve(cp); }, function (err) { return resolve(cp); }); + messageStream(cp.stdout).on("data", this.onMessage); + this.sendRequest(cp, "ping", null, true).then(res => resolve(cp), err => resolve(cp)); }); - return this.serverPromise.catch(function (error) { - _this.serverPromise = null; + return this.serverPromise.catch(error => { + this.serverPromise = null; throw error; }); } else { - throw new Error("Server already started: " + this.tsServerPath); + throw new Error(`Server already started: ${this.tsServerPath}`); } - }; - return TypescriptServiceClient; -}()); + } +} +exports.TypescriptServiceClient = TypescriptServiceClient; TypescriptServiceClient.commandWithResponse = { completions: true, projectInfo: true, quickinfo: true }; -exports.TypescriptServiceClient = TypescriptServiceClient; function isEvent(res) { return res.type === "event"; } @@ -150,19 +146,16 @@ function isResponse(res) { function messageStream(input) { return input.pipe(byline()).pipe(new MessageStream()); } -var MessageStream = (function (_super) { - tslib_1.__extends(MessageStream, _super); - function MessageStream() { - var _this = _super.call(this, { objectMode: true }) || this; - _this.lineCount = 1; - return _this; - } - MessageStream.prototype._transform = function (line, encoding, callback) { +class MessageStream extends stream_1.Transform { + constructor() { + super({ objectMode: true }); + this.lineCount = 1; + } + _transform(line, encoding, callback) { if (this.lineCount % 2 === 0) { this.push(JSON.parse(line)); } this.lineCount += 1; callback(null); - }; - return MessageStream; -}(stream_1.Transform)); + } +} diff --git a/dist/client/clientResolver.js b/dist/client/clientResolver.js index 85241a120..9c603c859 100644 --- a/dist/client/clientResolver.js +++ b/dist/client/clientResolver.js @@ -1,44 +1,54 @@ "use strict"; -var tslib_1 = require("tslib"); -var client_1 = require("./client"); -var events = require("events"); -var path = require("path"); -var nodeResolve = require("resolve"); -var defaultServerPath = require.resolve("typescript/bin/tsserver"); -var ClientResolver = (function (_super) { - tslib_1.__extends(ClientResolver, _super); - function ClientResolver() { - var _this = _super.apply(this, arguments) || this; - _this.clients = {}; - return _this; +const tslib_1 = require("tslib"); +const client_1 = require("./client"); +const events = require("events"); +const path = require("path"); +const nodeResolve = require("resolve"); +const defaultServerPath = require.resolve("typescript/bin/tsserver"); +class ClientResolver extends events.EventEmitter { + constructor() { + super(...arguments); + this.clients = {}; } - ClientResolver.prototype.get = function (filePath) { - var _this = this; + on(event, callback) { + return super.on(event, callback); + } + get(filePath) { return resolveServer(filePath) - .catch(function () { return defaultServerPath; }) - .then(function (serverPath) { - if (_this.clients[serverPath]) { - return _this.clients[serverPath].client; + .catch(() => defaultServerPath) + .then(serverPath => { + if (this.clients[serverPath]) { + return this.clients[serverPath].client; } - var entry = _this.clients[serverPath] = { + const entry = this.clients[serverPath] = { client: new client_1.TypescriptServiceClient(serverPath), pending: [], }; entry.client.startServer(); - entry.client.on("pendingRequestsChange", function (pending) { + entry.client.on("pendingRequestsChange", pending => { entry.pending = pending; - _this.emit("pendingRequestsChange"); + this.emit("pendingRequestsChange"); }); + const diagnosticHandler = (type, result) => { + this.emit("diagnostics", { + type, + serverPath, + filePath: result.file, + 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; }); - }; - return ClientResolver; -}(events.EventEmitter)); + } +} exports.ClientResolver = ClientResolver; function resolveServer(sourcePath) { - var basedir = path.dirname(sourcePath); - return new Promise(function (resolve, reject) { - nodeResolve("typescript/bin/tsserver", { basedir: basedir }, function (err, resolvedPath) { + const basedir = path.dirname(sourcePath); + return new Promise((resolve, reject) => { + nodeResolve("typescript/bin/tsserver", { basedir }, (err, resolvedPath) => { if (err) { reject(err); } diff --git a/dist/client/findServer.js b/dist/client/findServer.js index fefc666dd..7124aa422 100644 --- a/dist/client/findServer.js +++ b/dist/client/findServer.js @@ -1,32 +1,31 @@ "use strict"; -var fs = require("fs"); -var path = require("path"); +const fs = require("fs"); +const path = require("path"); function findTypescriptServers(root) { - var results = []; + const results = []; if (!path.isAbsolute(root)) { throw new Error("Argument should be an absolute path"); } - return new Promise(function (resolve) { - walk(root, function () { + return new Promise(resolve => { + walk(root, () => { resolve(results); }); }); function walk(dir, done) { - fs.readdir(dir, function (err, files) { + fs.readdir(dir, (err, files) => { if (err || files.length === 0) return done(); - var doneEntry = after(files.length, function () { + const doneEntry = after(files.length, () => { done(); }); - for (var _i = 0, files_1 = files; _i < files_1.length; _i++) { - var entry = files_1[_i]; + for (const entry of files) { if (entry === "node_modules") { - fs.stat(path.join(dir, entry, "typescript"), function (err) { + fs.stat(path.join(dir, entry, "typescript"), err => { if (err) { doneEntry(); } else { - getServerInfo(dir, function (err, info) { + getServerInfo(dir, (err, info) => { if (info) results.push(info); doneEntry(); @@ -46,20 +45,20 @@ function findTypescriptServers(root) { } exports.findTypescriptServers = findTypescriptServers; function getServerInfo(prefix, callback) { - var tsDir = path.join(prefix, "node_modules", "typescript"); - fs.readFile(path.join(tsDir, "package.json"), "utf8", function (err, pkg) { + const tsDir = path.join(prefix, "node_modules", "typescript"); + fs.readFile(path.join(tsDir, "package.json"), "utf8", (err, pkg) => { if (err) return callback(err, null); try { - var version_1 = JSON.parse(pkg).version; - var tsServerPath_1 = path.join(tsDir, "bin", "tsserver"); - fs.stat(tsServerPath_1, function (err, stat) { + const version = JSON.parse(pkg).version; + const tsServerPath = path.join(tsDir, "bin", "tsserver"); + fs.stat(tsServerPath, (err, stat) => { if (err) return callback(err, null); callback(null, { - binPath: tsServerPath_1, - prefix: prefix, - version: version_1 + binPath: tsServerPath, + prefix, + version }); }); } @@ -69,7 +68,7 @@ function getServerInfo(prefix, callback) { }); } function after(count, callback) { - var called = 0; + let called = 0; return function () { called++; if (called >= count) { diff --git a/dist/globals.js b/dist/globals.js deleted file mode 100644 index e69de29bb..000000000 diff --git a/dist/hyperclickProvider.js b/dist/hyperclickProvider.js index 0424f3b4a..16c66f2af 100644 --- a/dist/hyperclickProvider.js +++ b/dist/hyperclickProvider.js @@ -1,5 +1,5 @@ "use strict"; -var TS_GRAMMARS = new Set(["source.ts", "source.tsx"]); +const TS_GRAMMARS = new Set(["source.ts", "source.tsx"]); exports.providerName = "typescript-hyperclick-provider"; exports.wordRegExp = /([A-Za-z0-9_])+|['"`](\\.|[^'"`\\\\])*['"`]/g; function getSuggestionForWord(textEditor, text, range) { @@ -8,7 +8,7 @@ function getSuggestionForWord(textEditor, text, range) { } return { range: range, - callback: function () { + callback() { } }; } diff --git a/dist/linter.js b/dist/linter.js deleted file mode 100644 index 3918c74e4..000000000 --- a/dist/linter.js +++ /dev/null @@ -1 +0,0 @@ -"use strict"; diff --git a/dist/main/atom/atomConfig.js b/dist/main/atom/atomConfig.js index 891e8b148..3335e2c9f 100644 --- a/dist/main/atom/atomConfig.js +++ b/dist/main/atom/atomConfig.js @@ -1,5 +1,5 @@ "use strict"; -var utils_1 = require("../lang/utils"); +const utils_1 = require("../lang/utils"); var packageName = 'atom-typescript'; function getConfig(nameLambda) { return atom.config.get(packageName + '.' + utils_1.getName(nameLambda)); @@ -7,8 +7,8 @@ function getConfig(nameLambda) { function setConfig(nameLambda, value) { return atom.config.set(packageName + '.' + utils_1.getName(nameLambda), value); } -var Config = (function () { - function Config() { +class Config { + constructor() { this.schema = { preferredQuoteCharacter: { title: 'Preferred quote character', @@ -27,35 +27,10 @@ var Config = (function () { } }; } - 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; -}()); + get preferredQuoteCharacter() { return getConfig(() => this.schema.preferredQuoteCharacter); } + get typescriptServices() { return getConfig(() => this.schema.typescriptServices); } + get showSemanticView() { return getConfig(() => this.schema.showSemanticView); } + set showSemanticView(value) { setConfig(() => this.schema.showSemanticView, value); } +} var config = new Config(); module.exports = config; diff --git a/dist/main/atom/atomUtils.js b/dist/main/atom/atomUtils.js index 3b75c3bfa..6ce4f987b 100644 --- a/dist/main/atom/atomUtils.js +++ b/dist/main/atom/atomUtils.js @@ -1,9 +1,9 @@ "use strict"; -var path = require("path"); -var fs = require("fs"); -var fsu = require("../utils/fsUtil"); -var _atom = require("atom"); -var url = require("url"); +const path = require("path"); +const fs = require("fs"); +const fsu = require("../utils/fsUtil"); +const _atom = require("atom"); +const url = require("url"); function getEditorPosition(editor) { var bufferPos = editor.getCursorBufferPosition(); return getEditorPositionForBufferPosition(editor, bufferPos); @@ -62,28 +62,28 @@ function getFilePathPosition() { var editor = atom.workspace.getActiveTextEditor(); var filePath = editor.getPath(); var position = getEditorPosition(editor); - return { filePath: filePath, position: position }; + return { filePath, position }; } 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; } activeEditors.forEach(addConsistentlyToMap); - var newPaths = filePaths.filter(function (p) { return !map[p]; }); + 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(function (editor) { return addConsistentlyToMap(editor); }); + var promises = newPaths.map(p => atom.workspace.open(p, {})); + return Promise.all(promises).then(editors => { + editors.forEach(editor => addConsistentlyToMap(editor)); return map; }); } @@ -97,24 +97,24 @@ function getRangeForTextSpan(editor, ts) { exports.getRangeForTextSpan = getRangeForTextSpan; 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 => fsu.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); } @@ -185,7 +185,7 @@ 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 ''; @@ -200,7 +200,7 @@ function uriForPath(uriProtocol, filePath) { } exports.uriForPath = uriForPath; 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()); @@ -212,7 +212,7 @@ function registerOpener(config) { }); atom.workspace.addOpener(function (uri, data) { try { - var protocol = url.parse(uri).protocol; + var { protocol } = url.parse(uri); } catch (error) { return; @@ -233,8 +233,7 @@ function getFilePathRelativeToAtomProject(filePath) { return '~' + atom.project.relativize(filePath); } exports.getFilePathRelativeToAtomProject = getFilePathRelativeToAtomProject; -function openFile(filePath, position) { - if (position === void 0) { position = {}; } +function openFile(filePath, position = {}) { var config = {}; if (position.line) { config.initialLine = position.line - 1; diff --git a/dist/main/atom/autoCompleteProvider.js b/dist/main/atom/autoCompleteProvider.js index c64e03f20..564dca154 100644 --- a/dist/main/atom/autoCompleteProvider.js +++ b/dist/main/atom/autoCompleteProvider.js @@ -1,8 +1,8 @@ "use strict"; -var tslib_1 = require("tslib"); -var atomUtils = require("./atomUtils"); -var fs = require("fs"); -var parent = require("../../worker/parent"); +const tslib_1 = require("tslib"); +const atomUtils = require("./atomUtils"); +const fs = require("fs"); +const atomts_1 = require("../atomts"); var explicitlyTriggered = false; function triggerAutocompletePlus() { atom.commands.dispatch(atom.views.getView(atom.workspace.getActiveTextEditor()), 'autocomplete-plus:activate'); @@ -15,50 +15,42 @@ exports.provider = { suggestionPriority: 3, excludeLowerPriority: false, getSuggestions: function (options) { - return tslib_1.__awaiter(this, void 0, void 0, function () { - var filePath, client, prefix; - return tslib_1.__generator(this, function (_a) { - switch (_a.label) { - case 0: - filePath = options.editor.getPath(); - if (!filePath || !fs.existsSync(filePath)) - return [2 /*return*/, []]; - return [4 /*yield*/, parent.clients.get(filePath)]; - case 1: - client = _a.sent(); - if (explicitlyTriggered) { - explicitlyTriggered = false; - } - else { - prefix = options.prefix.trim(); - if (prefix === '' || prefix === ';' || prefix === '{') { - return [2 /*return*/, Promise.resolve([])]; - } - } - return [2 /*return*/, client.executeCompletions({ - file: filePath, - prefix: options.prefix, - line: options.bufferPosition.row + 1, - offset: options.bufferPosition.column + 1 - }).then(function (resp) { - console.log("prefix", options.prefix); - return resp.body.map(function (c) { - var prefix = options.prefix; - if (c.name && c.name.startsWith('$')) { - prefix = "$" + prefix; - } - return { - text: c.name, - replacementPrefix: prefix === "." ? "" : prefix.trim(), - rightLabel: c.name, - leftLabel: c.kind, - type: atomUtils.kindToType(c.kind), - description: null, - }; - }); - })]; + return tslib_1.__awaiter(this, void 0, void 0, function* () { + const filePath = options.editor.getPath(); + if (!filePath || !fs.existsSync(filePath)) + return []; + const client = yield atomts_1.clientResolver.get(filePath); + if (explicitlyTriggered) { + explicitlyTriggered = false; + } + else { + const prefix = options.prefix.trim(); + if (prefix === '' || prefix === ';' || prefix === '{') { + return Promise.resolve([]); } - }); + } + return client.executeCompletions({ + file: filePath, + prefix: options.prefix, + line: options.bufferPosition.row + 1, + offset: options.bufferPosition.column + 1 + }).then(resp => { + console.log("prefix", options.prefix); + return resp.body.map(c => { + var prefix = options.prefix; + if (c.name && c.name.startsWith('$')) { + prefix = "$" + prefix; + } + return { + text: c.name, + replacementPrefix: prefix === "." ? "" : prefix.trim(), + rightLabel: c.name, + leftLabel: c.kind, + type: atomUtils.kindToType(c.kind), + description: null, + }; + }); + }).catch(() => []); }); }, }; diff --git a/dist/main/atom/commands/commands.js b/dist/main/atom/commands/commands.js index 06b9c814a..d79cbbe23 100644 --- a/dist/main/atom/commands/commands.js +++ b/dist/main/atom/commands/commands.js @@ -2,47 +2,46 @@ function __export(m) { for (var p in m) if (!exports.hasOwnProperty(p)) exports[p] = m[p]; } -var parent = require("../../../worker/parent"); -var atomUtils = require("../atomUtils"); -var autoCompleteProvider = require("../autoCompleteProvider"); -var contextView = require("../views/contextView"); -var typeOverlayView_1 = require("../views/typeOverlayView"); -var gotoHistory = require("../gotoHistory"); -var mainPanelView_1 = require("../views/mainPanelView"); +const atomts_1 = require("../../atomts"); +const atomUtils = require("../atomUtils"); +const autoCompleteProvider = require("../autoCompleteProvider"); +const contextView = require("../views/contextView"); +const typeOverlayView_1 = require("../views/typeOverlayView"); +const gotoHistory = require("../gotoHistory"); +const mainPanelView_1 = require("../views/mainPanelView"); __export(require("../components/componentRegistry")); function registerCommands() { var theContextView; - atom.commands.add('atom-text-editor', 'typescript:context-actions', function (e) { + 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', function (e) { + atom.commands.add('atom-text-editor', 'typescript:autocomplete', (e) => { autoCompleteProvider.triggerAutocompletePlus(); }); - atom.commands.add('atom-workspace', 'typescript:show-type', function (e) { + 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 = cursor.getBufferPosition(); var filePath = editor.getPath(); - parent.clients.get(filePath).then(function (client) { + atomts_1.clientResolver.get(filePath).then(client => { return client.executeQuickInfo({ file: filePath, line: position.row + 1, offset: position.column + 1 - }).then(function (_a) { - var _b = _a.body, displayString = _b.displayString, documentation = _b.documentation; + }).then(({ body: { displayString, documentation } }) => { var decoration = editor.decorateMarker(cursor.getMarker(), { type: 'overlay', item: typeOverlayView_1.create(displayString, documentation) }); - var onKeydown = function (e) { + var onKeydown = (e) => { if (e.keyCode == 27) { destroyTypeOverlay(); } }; - var destroyTypeOverlay = function () { + var destroyTypeOverlay = () => { decoration.destroy(); cursorListener.dispose(); editorView.removeEventListener('blur', destroyTypeOverlay); @@ -51,16 +50,16 @@ function registerCommands() { var cursorListener = editor.onDidChangeCursorPosition(destroyTypeOverlay); editorView.addEventListener('blur', destroyTypeOverlay); editorView.addEventListener('keydown', onKeydown); - }).catch(function () { }); + }).catch(() => { }); }); }); - atom.commands.add('atom-workspace', 'typescript:go-to-next', function (e) { + atom.commands.add('atom-workspace', 'typescript:go-to-next', (e) => { gotoHistory.gotoNext(); }); - atom.commands.add('atom-workspace', 'typescript:go-to-previous', function (e) { + atom.commands.add('atom-workspace', 'typescript:go-to-previous', (e) => { gotoHistory.gotoPrevious(); }); - atom.commands.add('atom-workspace', 'typescript:sync', function (e) { + atom.commands.add('atom-workspace', 'typescript:sync', (e) => { if (!atomUtils.commandForTypeScript(e)) return; mainPanelView_1.panelView.softReset(); diff --git a/dist/main/atom/components/ts-view.js b/dist/main/atom/components/ts-view.js index 422cdcd6f..4b6b2d9fe 100644 --- a/dist/main/atom/components/ts-view.js +++ b/dist/main/atom/components/ts-view.js @@ -1,11 +1,6 @@ "use strict"; -var tslib_1 = require("tslib"); -var TsView = (function (_super) { - tslib_1.__extends(TsView, _super); - function TsView() { - return _super.apply(this, arguments) || this; - } - TsView.prototype.createdCallback = function () { +class TsView extends HTMLElement { + createdCallback() { var preview = this.innerText; this.innerText = ""; var editorElement = this.editorElement = document.createElement('atom-text-editor'); @@ -18,11 +13,10 @@ var TsView = (function (_super) { editor.setGrammar(grammar); editor.setSoftWrapped(true); this.appendChild(editorElement); - }; - TsView.prototype.text = function (text) { + } + text(text) { this.editor.setText(text); - }; - return TsView; -}(HTMLElement)); + } +} exports.TsView = TsView; document.registerElement('ts-view', TsView); diff --git a/dist/main/atom/fileStatusCache.js b/dist/main/atom/fileStatusCache.js index e5fa82b07..03d3bcab1 100644 --- a/dist/main/atom/fileStatusCache.js +++ b/dist/main/atom/fileStatusCache.js @@ -1,7 +1,7 @@ "use strict"; -var fsUtil_1 = require("../utils/fsUtil"); +const fsUtil_1 = require("../utils/fsUtil"); ; -var fileStatuses = {}; +let fileStatuses = {}; function getFileStatus(filePath) { filePath = fsUtil_1.consistentPath(filePath); if (!fileStatuses[filePath]) { diff --git a/dist/main/atom/gotoHistory.js b/dist/main/atom/gotoHistory.js index acb6dbf9c..03201b11f 100644 --- a/dist/main/atom/gotoHistory.js +++ b/dist/main/atom/gotoHistory.js @@ -17,7 +17,7 @@ function gotoLine(filePath, line, col, list) { else { atom.workspace.getActiveTextEditor().cursors[0].setBufferPosition([line - 1, col]); } - list.lastPosition = { filePath: filePath, line: line, col: col }; + list.lastPosition = { filePath, line, col }; } exports.gotoLine = gotoLine; function findCurrentIndexInList() { @@ -28,7 +28,7 @@ function findCurrentIndexInList() { 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; }); + var index = indexOf(exports.activeList.members, (item) => item.filePath == lastPosition.filePath && item.line == lastPosition.line); if (index == -1) { return 0; } diff --git a/dist/main/atom/tooltipManager.js b/dist/main/atom/tooltipManager.js index e265bb961..fc8076071 100644 --- a/dist/main/atom/tooltipManager.js +++ b/dist/main/atom/tooltipManager.js @@ -1,14 +1,14 @@ "use strict"; -var atomUtils = require("./atomUtils"); -var parent = require("../../worker/parent"); -var path = require("path"); -var fs = require("fs"); -var emissary = require("emissary"); +const atomUtils = require("./atomUtils"); +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); @@ -25,13 +25,13 @@ function attach(editorView, editor) { if (!fs.existsSync(filePath)) { return; } - var clientPromise = parent.clients.get(filePath); + var clientPromise = atomts_1.clientResolver.get(filePath); var scroll = getFromShadowDom(editorView, '.scroll-view'); var subscriber = new Subscriber(); var exprTypeTimeout = null; var exprTypeTooltip = null; var lastExprTypeBufferPt; - subscriber.subscribe(scroll, 'mousemove', function (e) { + subscriber.subscribe(scroll, 'mousemove', (e) => { var pixelPt = pixelPositionFromMouseEvent(editorView, e); var screenPt = editor.screenPositionForPixelPosition(pixelPt); var bufferPt = editor.bufferPositionForScreenPosition(screenPt); @@ -39,11 +39,11 @@ function attach(editorView, editor) { 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', (e) => clearExprTypeTimeout()); + subscriber.subscribe(scroll, 'keydown', (e) => clearExprTypeTimeout()); + editor.onDidDestroy(() => deactivate()); function showExpressionType(e) { if (exprTypeTooltip) return; @@ -64,21 +64,18 @@ function attach(editorView, editor) { bottom: e.clientY + offset }; exprTypeTooltip = new TooltipView(tooltipRect); - clientPromise.then(function (client) { + clientPromise.then(client => { client.executeQuickInfo({ file: filePath, line: bufferPt.row + 1, offset: bufferPt.column + 1 - }).then(function (_a) { - var _b = _a.body, displayString = _b.displayString, documentation = _b.documentation; - var message = "" + escape(displayString) + ""; + }).then(({ body: { displayString, documentation } }) => { + var message = `${escape(displayString)}`; if (documentation) { - message = message + ("
    " + escape(documentation).replace(/(?:\r\n|\r|\n)/g, '
    ') + "
    "); + message = message + `
    ${escape(documentation).replace(/(?:\r\n|\r|\n)/g, '
    ')}
    `; } - if (exprTypeTooltip) { - exprTypeTooltip.updateText(message); - } - }, function () { }); + exprTypeTooltip.updateText(message); + }, () => { }); }); } function deactivate() { diff --git a/dist/main/atom/views/contextView.js b/dist/main/atom/views/contextView.js index ff330717e..b7a2dff15 100644 --- a/dist/main/atom/views/contextView.js +++ b/dist/main/atom/views/contextView.js @@ -1,33 +1,26 @@ "use strict"; -var tslib_1 = require("tslib"); -var sp = require("atom-space-pen-views"); -var mainPanelView = require("./mainPanelView"); +const sp = require("atom-space-pen-views"); +const mainPanelView = require("./mainPanelView"); var titles = { togglePanel: 'Toggle TypeScript Panel', tabErrors: 'Tab: Errors in Open Files', tabLastBuild: 'Tab: Last Build Output', tabReferences: 'Tab: Find References', }; -var items = Object.keys(titles).map(function (item) { return { title: titles[item] }; }); -var ContextView = (function (_super) { - tslib_1.__extends(ContextView, _super); - function ContextView() { - var _this = _super.apply(this, arguments) || this; - _this.panel = null; - return _this; +var items = Object.keys(titles).map(item => { return { title: titles[item] }; }); +class ContextView extends sp.SelectListView { + constructor() { + super(...arguments); + this.panel = null; } - 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) { + get $() { + return this; + } + setItems(items) { super.setItems(items); } + viewForItem(item) { + return `
  • ${item.title}
  • `; + } + confirmed(item) { if (item.title == titles.togglePanel) { mainPanelView.panelView.toggle(); } @@ -41,23 +34,22 @@ var ContextView = (function (_super) { mainPanelView.panelView.referencesPanelSelected(); } this.hide(); - }; - ContextView.prototype.getFilterKey = function () { return 'title'; }; - ContextView.prototype.show = function () { + } + getFilterKey() { return 'title'; } + show() { this.storeFocusedElement(); if (!this.panel) this.panel = atom.workspace.addModalPanel({ item: this }); this.panel.show(); this.setItems(items); this.focusFilterEditor(); - }; - ContextView.prototype.hide = function () { + } + hide() { this.panel.hide(); this.restoreFocus(); - }; - ContextView.prototype.cancelled = function () { + } + cancelled() { this.hide(); - }; - return ContextView; -}(sp.SelectListView)); + } +} exports.ContextView = ContextView; diff --git a/dist/main/atom/views/documentationView.js b/dist/main/atom/views/documentationView.js deleted file mode 100644 index 2242d9a9c..000000000 --- a/dist/main/atom/views/documentationView.js +++ /dev/null @@ -1,62 +0,0 @@ -"use strict"; -var tslib_1 = require("tslib"); -var view = require("./view"); -var $ = view.$; -var DocumentationView = (function (_super) { - tslib_1.__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/fileSymbolsView.js b/dist/main/atom/views/fileSymbolsView.js index ffc7856f4..4d6bd10e7 100644 --- a/dist/main/atom/views/fileSymbolsView.js +++ b/dist/main/atom/views/fileSymbolsView.js @@ -1,51 +1,49 @@ "use strict"; -var tslib_1 = require("tslib"); -var sp = require("atom-space-pen-views"); -var atomUtils = require("../atomUtils"); -var FileSymbolsView = (function (_super) { - tslib_1.__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) { +const sp = require("atom-space-pen-views"); +const atomUtils = require("../atomUtils"); +class FileSymbolsView extends sp.SelectListView { + constructor() { + super(...arguments); + this.panel = null; + } + get $() { + return this; + } + setNavBarItems(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) { + super.setItems(items); + } + viewForItem(item) { + return ` +
  • +
    ${Array(item.indent * 2).join(' ') + (item.indent ? "\u221F " : '') + item.text}
    +
    ${item.kind}
    +
    line: ${item.position.line + 1}
    +
  • + `; + } + confirmed(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 () { + } + getFilterKey() { return 'text'; } + show() { this.storeFocusedElement(); if (!this.panel) this.panel = atom.workspace.addModalPanel({ item: this }); this.panel.show(); this.focusFilterEditor(); - }; - FileSymbolsView.prototype.hide = function () { + } + hide() { this.panel.hide(); this.restoreFocus(); - }; - FileSymbolsView.prototype.cancelled = function () { + } + cancelled() { 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 index 1c6bbe1e3..0b229dbf1 100644 --- a/dist/main/atom/views/lineMessageView.js +++ b/dist/main/atom/views/lineMessageView.js @@ -1,36 +1,30 @@ "use strict"; -var tslib_1 = require("tslib"); -var view = require("./view"); +const view = require("./view"); var $ = view.$; -var LineMessageView = (function (_super) { - tslib_1.__extends(LineMessageView, _super); - function LineMessageView() { - return _super.apply(this, arguments) || this; - } - LineMessageView.content = function () { - var _this = this; +class LineMessageView extends view.View { + static content() { return this.div({ class: 'line-message' - }, function () { - _this.div({ + }, () => { + this.div({ class: 'text-subtle inline-block', outlet: 'position', click: 'goToLine', style: 'cursor: pointer;' }); - _this.div({ + this.div({ class: 'message inline-block', outlet: 'contents' }); - _this.pre({ + this.pre({ class: 'preview', outlet: 'code', click: 'goToLine', style: 'cursor: pointer;' }); }); - }; - LineMessageView.prototype.init = function () { + } + init() { var message = 'at line ' + this.options.line; if (this.options.file !== undefined) { message += ', file ' + this.options.file; @@ -43,11 +37,11 @@ var LineMessageView = (function (_super) { else { this.code.remove(); } - }; - LineMessageView.prototype.goToLine = function () { + } + goToLine() { this.options.goToLine(this.options.file, this.options.line, this.options.col); - }; - LineMessageView.prototype.getSummary = function () { + } + getSummary() { var pos = this.options.line.toString(); if (this.options.file !== undefined) { pos += ', ' + this.options.file; @@ -61,7 +55,6 @@ var LineMessageView = (function (_super) { .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 index a79a9d2bd..df518d011 100644 --- a/dist/main/atom/views/mainPanelView.js +++ b/dist/main/atom/views/mainPanelView.js @@ -1,118 +1,111 @@ "use strict"; -var tslib_1 = require("tslib"); -var view = require("./view"); -var lineMessageView = require("./lineMessageView"); -var atomUtils = require("../atomUtils"); -var utils = require("../../lang/utils"); +const tslib_1 = require("tslib"); +const view = require("./view"); +const lineMessageView = require("./lineMessageView"); +const atomUtils = require("../atomUtils"); var panelHeaders = { error: 'Errors In Open Files', build: 'Last Build Output', references: 'References' }; -var gotoHistory = require("../gotoHistory"); -var MainPanelView = (function (_super) { - tslib_1.__extends(MainPanelView, _super); - function MainPanelView() { - var _this = _super.apply(this, arguments) || this; - _this.pendingRequests = []; - _this.expanded = false; - _this.clearedError = true; - return _this; +const gotoHistory = require("../gotoHistory"); +class MainPanelView extends view.View { + constructor() { + super(...arguments); + this.pendingRequests = []; + this.expanded = false; + this.clearedError = true; } - 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); - }; + static content() { + var btn = (view, text, className = '') => 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({ + }, () => { + this.div({ class: 'layout horizontal', style: '-webkit-user-select: none; flex-wrap: wrap', dblclick: 'toggle' - }, function () { - _this.span({ + }, () => { + this.span({ class: 'layout horizontal atomts-panel-header', style: 'align-items: center' - }, function () { - _this.span({ + }, () => { + 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.span({ class: 'icon-microscope' }); + this.span({ style: 'font-weight: bold' }, 'TypeScript'); }); - _this.div({ + 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({ + this.span({ class: 'layout horizontal atomts-panel-header', style: 'align-items: center; flex: 1 1 auto; line-height: 24px;' - }, function () { - _this.div({ + }, () => { + this.div({ style: 'cursor: pointer;', click: 'clickedCurrentTsconfigFilePath' - }, function () { - _this.span({ + }, () => { + this.span({ outlet: 'tsconfigInUse' }); }); - _this.div({ + this.div({ style: 'overflow-x: visible; white-space: nowrap;' - }, function () { - _this.span({ + }, () => { + this.span({ style: 'margin-left: 10px; transition: color 1s', outlet: 'fileStatus' }); }); - _this.div({ + this.div({ class: 'heading-summary flex', style: 'margin-left: 5px; overflow: hidden; white-space:nowrap; text-overflow: ellipsis', outlet: 'summary' }); - _this.progress({ + this.progress({ class: 'inline-block build-progress', style: 'display: none; color: red', outlet: 'buildProgress' }); - _this.span({ + this.span({ class: 'section-pending', outlet: 'sectionPending', click: 'showPending' - }, function () { - _this.span({ + }, () => { + this.span({ outlet: 'txtPendingCount', style: 'cursor: pointer; margin-left: 5px', }); - _this.span({ + this.span({ class: 'loading loading-spinner-tiny inline-block', style: 'cursor: pointer; margin-left: 5px' }); }); - _this.div({ + this.div({ class: 'heading-buttons', style: 'margin-left: 5px' - }, function () { - _this.span({ + }, () => { + this.span({ class: 'heading-fold icon-unfold', style: 'cursor: pointer; margin-right: 10px', outlet: 'btnFold', click: 'toggle' }); - _this.span({ + this.span({ class: 'heading-fold icon-sync', style: 'cursor: pointer', outlet: 'btnSoftReset', @@ -120,44 +113,44 @@ var MainPanelView = (function (_super) { }); }); }); - _this.div({ + this.div({ class: 'panel-body atomts-panel-body', outlet: 'errorBody', style: 'overflow-y: auto; flex: 1 0 100%; display: none' }); - _this.div({ + this.div({ class: 'panel-body atomts-panel-body', outlet: 'buildBody', style: 'overflow-y: auto; flex: 1 0 100%; display: none' }); - _this.div({ + 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 )"); + } + 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.referencesPanelBtn.html(`${panelHeaders.references} ( No Search )`); this.referencesBody.html(' You haven\'t searched for TypeScript references yet. '); - }; - MainPanelView.prototype.softReset = function () { + } + softReset() { console.log("soft reset"); - }; - MainPanelView.prototype.setTsconfigInUse = function (tsconfigFilePath) { + } + setTsconfigInUse(tsconfigFilePath) { this.fullTsconfigPath = tsconfigFilePath; if (!this.fullTsconfigPath) { this.tsconfigInUse.text('no tsconfig.json'); } else { var path = atomUtils.getFilePathRelativeToAtomProject(tsconfigFilePath); - this.tsconfigInUse.text("" + path); + this.tsconfigInUse.text(`${path}`); } - }; - MainPanelView.prototype.clickedCurrentTsconfigFilePath = function () { + } + clickedCurrentTsconfigFilePath() { if (!this.fullTsconfigPath) { atom.notifications.addInfo("No tsconfig for current file"); return; @@ -165,15 +158,15 @@ var MainPanelView = (function (_super) { else { atomUtils.openFile(this.fullTsconfigPath); } - }; - MainPanelView.prototype.updateFileStatus = function (filePath) { - }; - MainPanelView.prototype.showPending = function () { + } + updateFileStatus(filePath) { + } + showPending() { atom.notifications.addInfo('Pending Requests:
    - ' + this.pendingRequests.join('
    - ')); - }; - MainPanelView.prototype.updatePendingRequests = function (pending) { + } + updatePendingRequests(pending) { this.pendingRequests = pending; - this.txtPendingCount.html("" + this.pendingRequests.length + ""); + this.txtPendingCount.html(`${this.pendingRequests.length}`); this.sectionPending.stop(); if (pending.length) { this.sectionPending.animate({ opacity: 0.5 }, 500); @@ -181,46 +174,44 @@ var MainPanelView = (function (_super) { else { this.sectionPending.animate({ opacity: 0 }, 200); } - }; - MainPanelView.prototype.errorPanelSelectedClick = function () { + } + errorPanelSelectedClick() { this.toggleIfThisIsntSelected(this.errorPanelBtn); this.errorPanelSelected(); - }; - MainPanelView.prototype.errorPanelSelected = function () { + } + errorPanelSelected() { this.selectPanel(this.errorPanelBtn, this.errorBody, gotoHistory.errorsInOpenFiles); - }; - MainPanelView.prototype.buildPanelSelectedClick = function () { + } + buildPanelSelectedClick() { this.toggleIfThisIsntSelected(this.buildPanelBtn); this.buildPanelSelected(); - }; - MainPanelView.prototype.buildPanelSelected = function () { + } + buildPanelSelected() { this.selectPanel(this.buildPanelBtn, this.buildBody, gotoHistory.buildOutput); - }; - MainPanelView.prototype.referencesPanelSelectedClick = function () { + } + referencesPanelSelectedClick() { this.toggleIfThisIsntSelected(this.referencesPanelBtn); this.referencesPanelSelected(); - }; - MainPanelView.prototype.referencesPanelSelected = function (forceExpand) { - if (forceExpand === void 0) { forceExpand = false; } + } + referencesPanelSelected(forceExpand = false) { this.selectPanel(this.referencesPanelBtn, this.referencesBody, gotoHistory.referencesOutput); - }; - MainPanelView.prototype.toggleIfThisIsntSelected = function (btn) { + } + toggleIfThisIsntSelected(btn) { if (btn.hasClass('selected')) { this.expanded = !this.expanded; } - }; - MainPanelView.prototype.selectPanel = function (btn, body, activeList) { - var _this = this; + } + selectPanel(btn, body, activeList) { var buttons = [this.errorPanelBtn, this.buildPanelBtn, this.referencesPanelBtn]; var bodies = [this.errorBody, this.buildBody, this.referencesBody]; - buttons.forEach(function (b) { + buttons.forEach(b => { if (b !== btn) b.removeClass('selected'); else b.addClass('selected'); }); - bodies.forEach(function (b) { - if (!_this.expanded) { + bodies.forEach(b => { + if (!this.expanded) { b.hide('fast'); } else { @@ -233,8 +224,8 @@ var MainPanelView = (function (_super) { }); gotoHistory.activeList = activeList; gotoHistory.activeList.lastPosition = null; - }; - MainPanelView.prototype.setActivePanel = function () { + } + setActivePanel() { if (this.errorPanelBtn.hasClass('selected')) { this.errorPanelSelected(); } @@ -244,28 +235,27 @@ var MainPanelView = (function (_super) { if (this.referencesPanelBtn.hasClass('selected')) { this.referencesPanelSelected(); } - }; - MainPanelView.prototype.toggle = function () { + } + toggle() { this.expanded = !this.expanded; this.setActivePanel(); - }; - MainPanelView.prototype.setReferences = function (references) { + } + setReferences(references) { this.referencesPanelSelected(true); this.referencesBody.empty(); if (references.length == 0) { - var title = panelHeaders.references + " ( No References )"; + 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 + " )"; + 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]; + for (let ref of references) { var view = new lineMessageView.LineMessageView({ - goToLine: function (filePath, line, col) { return gotoHistory.gotoLine(filePath, line, col, gotoHistory.referencesOutput); }, + goToLine: (filePath, line, col) => gotoHistory.gotoLine(filePath, line, col, gotoHistory.referencesOutput), message: '', line: ref.position.line + 1, col: ref.position.col, @@ -275,20 +265,20 @@ var MainPanelView = (function (_super) { this.referencesBody.append(view.$); gotoHistory.referencesOutput.members.push({ filePath: ref.filePath, line: ref.position.line + 1, col: ref.position.col }); } - }; - MainPanelView.prototype.clearError = function () { + } + clearError() { this.clearedError = true; this.clearSummary(); this.errorBody.empty(); - }; - MainPanelView.prototype.addError = function (view) { + } + addError(view) { if (this.clearedError && view.getSummary) { this.setErrorSummary(view.getSummary()); } this.clearedError = false; this.errorBody.append(view.$); - }; - MainPanelView.prototype.setErrorSummary = function (summary) { + } + setErrorSummary(summary) { var message = summary.summary, className = summary.className, handler = summary.handler || undefined; this.summary.html(message); if (className) { @@ -297,43 +287,49 @@ var MainPanelView = (function (_super) { if (handler) { handler(this.summary); } - }; - MainPanelView.prototype.clearSummary = function () { + } + clearSummary() { this.summary.html(''); this.summary.off(); - }; - MainPanelView.prototype.setErrorPanelErrorCount = function (fileErrorCount, totalErrorCount) { - var title = panelHeaders.error + " ( No Errors )"; + } + setErrorPanelErrorCount(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 )"; + 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); - }; - MainPanelView.prototype.setBuildPanelCount = function (errorCount, inProgressBuild) { - if (inProgressBuild === void 0) { inProgressBuild = false; } + } + setBuildPanelCount(errorCount, inProgressBuild = false) { var titleMain = inProgressBuild ? "Build Progress" : panelHeaders.build; - var title = titleMain + " ( No Errors )"; + var title = `${titleMain} ( No Errors )`; if (errorCount > 0) { - title = titleMain + " (\n " + errorCount + " \n error" + (errorCount === 1 ? "" : "s") + " \n )"; + title = `${titleMain} ( + ${errorCount} + error${errorCount === 1 ? "" : "s"} + )`; } else { if (!inProgressBuild) this.buildBody.html('No errors in last build \u2665'); } this.buildPanelBtn.html(title); - }; - MainPanelView.prototype.clearBuild = function () { + } + clearBuild() { this.buildBody.empty(); - }; - MainPanelView.prototype.addBuild = function (view) { + } + addBuild(view) { this.buildBody.append(view.$); - }; - MainPanelView.prototype.setBuildProgress = function (progress) { - var _this = this; + } + setBuildProgress(progress) { if (progress.builtCount == 1) { this.buildProgress.show(); this.buildProgress.removeClass('warn'); @@ -352,9 +348,9 @@ var MainPanelView = (function (_super) { 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); }, + 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, @@ -364,9 +360,8 @@ var MainPanelView = (function (_super) { 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() { @@ -389,55 +384,3 @@ function hide() { 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 index d370eb1d8..cb87c7e6f 100644 --- a/dist/main/atom/views/plainMessageView.js +++ b/dist/main/atom/views/plainMessageView.js @@ -1,27 +1,21 @@ "use strict"; -var tslib_1 = require("tslib"); -var view = require("./view"); -var PlainMessageView = (function (_super) { - tslib_1.__extends(PlainMessageView, _super); - function PlainMessageView() { - return _super.apply(this, arguments) || this; - } - PlainMessageView.content = function () { +const view = require("./view"); +class PlainMessageView extends view.View { + static content() { this.div({ class: 'plain-message' }); - }; - PlainMessageView.prototype.init = function () { + } + init() { this.$.html(this.options.message); this.$.addClass(this.options.className); - }; - PlainMessageView.prototype.getSummary = function () { + } + getSummary() { 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 index 06732f14a..fa1ca8786 100644 --- a/dist/main/atom/views/projectSymbolsView.js +++ b/dist/main/atom/views/projectSymbolsView.js @@ -1,61 +1,55 @@ "use strict"; -var tslib_1 = require("tslib"); -var sp = require("atom-space-pen-views"); -var atomUtils = require("../atomUtils"); -var ProjectSymbolsView = (function (_super) { - tslib_1.__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); +const sp = require("atom-space-pen-views"); +const atomUtils = require("../atomUtils"); +class ProjectSymbolsView extends sp.SelectListView { + constructor() { + super(...arguments); + this.panel = null; + } + get $() { + return this; + } + get filterView() { + return { + $: this.filterEditorView, + model: this.filterEditorView.model + }; + } + setNavBarItems(tsItems) { + super.setMaxItems(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) { + super.setItems(items); + } + viewForItem(item) { + return ` +
  • +
    ${item.name}
    +
    ${item.kind}
    +
    ${item.fileName} : ${item.position.line + 1}
    +
  • + `; + } + confirmed(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 () { + } + getFilterKey() { return 'name'; } + show() { this.storeFocusedElement(); if (!this.panel) this.panel = atom.workspace.addModalPanel({ item: this }); this.panel.show(); this.focusFilterEditor(); - }; - ProjectSymbolsView.prototype.hide = function () { + } + hide() { this.panel.hide(); this.restoreFocus(); - }; - ProjectSymbolsView.prototype.cancelled = function () { + } + cancelled() { this.hide(); - }; - return ProjectSymbolsView; -}(sp.SelectListView)); + } +} exports.ProjectSymbolsView = ProjectSymbolsView; diff --git a/dist/main/atom/views/renameView.js b/dist/main/atom/views/renameView.js index b868f8392..878cb9f49 100644 --- a/dist/main/atom/views/renameView.js +++ b/dist/main/atom/views/renameView.js @@ -1,49 +1,45 @@ "use strict"; -var tslib_1 = require("tslib"); -var view = require("./view"); +const view = require("./view"); var $ = view.$; var html = require('../../../../views/renameView.html'); -var RenameView = (function (_super) { - tslib_1.__extends(RenameView, _super); - function RenameView() { - var _this = _super.apply(this, arguments) || this; - _this.editorAtRenameStart = null; - return _this; +class RenameView extends view.View { + constructor() { + super(...arguments); + this.editorAtRenameStart = null; } - RenameView.prototype.init = function () { - var _this = this; - $(atom.views.getView(atom.workspace)).on('keydown', function (e) { + 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 () { + } + clearView() { if (this.editorAtRenameStart && !this.editorAtRenameStart.isDestroyed()) { var view = atom.views.getView(this.editorAtRenameStart); view.focus(); @@ -51,8 +47,8 @@ var RenameView = (function (_super) { panel.hide(); this.options = {}; this.editorAtRenameStart = null; - }; - RenameView.prototype.renameThis = function (options) { + } + renameThis(options) { this.options = options; this.editorAtRenameStart = atom.workspace.getActiveTextEditor(); panel.show(); @@ -66,10 +62,11 @@ var RenameView = (function (_super) { 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)); + this.fileCount.html(`
    + Files Counts: Already Open ( ${options.openFiles.length} ) and Currently Closed ( ${options.closedFiles.length} ) +
    `); + } +} RenameView.content = html; exports.RenameView = RenameView; var panel; diff --git a/dist/main/atom/views/simpleOverlaySelectionView.js b/dist/main/atom/views/simpleOverlaySelectionView.js index d356d7348..598fb93d8 100644 --- a/dist/main/atom/views/simpleOverlaySelectionView.js +++ b/dist/main/atom/views/simpleOverlaySelectionView.js @@ -1,5 +1,4 @@ "use strict"; -var tslib_1 = require("tslib"); var singleton; function default_1(options, editor) { if (!singleton) @@ -14,51 +13,45 @@ function default_1(options, editor) { } Object.defineProperty(exports, "__esModule", { value: true }); exports.default = default_1; -var sp = require("atom-space-pen-views"); -var SimpleOverlaySelectListView = (function (_super) { - tslib_1.__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; +const sp = require("atom-space-pen-views"); +class SimpleOverlaySelectListView extends sp.SelectListView { + constructor(options, editor) { + super(); + this.options = options; + this.editor = editor; + this.$.addClass('atomts-overlay'); + this.filterEditorView.model.placeholderText = 'Filter list'; } - 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) { + get $() { + return this; + } + setItems() { + super.setItems(this.options.items); + } + viewForItem(item) { + return `
  • + ${this.options.viewForItem(item)} +
  • `; + } + confirmed(item) { this.options.confirmed(item); this.hide(); - }; - SimpleOverlaySelectListView.prototype.getFilterKey = function () { + } + getFilterKey() { return this.options.filterKey; - }; - SimpleOverlaySelectListView.prototype.show = function () { - var _this = this; + } + show() { 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 () { + setTimeout(() => this.focusFilterEditor(), 100); + } + hide() { this.restoreFocus(); if (this._overlayDecoration) this._overlayDecoration.destroy(); - }; - SimpleOverlaySelectListView.prototype.cancelled = function () { + } + cancelled() { 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 3e5e436aa..4b5fb1daf 100644 --- a/dist/main/atom/views/simpleSelectionView.js +++ b/dist/main/atom/views/simpleSelectionView.js @@ -1,5 +1,4 @@ "use strict"; -var tslib_1 = require("tslib"); var singleton; function simpleSelectionView(options) { if (!singleton) @@ -12,57 +11,52 @@ function simpleSelectionView(options) { return singleton; } exports.simpleSelectionView = simpleSelectionView; -var sp = require("atom-space-pen-views"); +const sp = require("atom-space-pen-views"); var $ = sp.$; -var SimpleSelectListView = (function (_super) { - tslib_1.__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; + this.panel = null; } - 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); + } + 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) { + } + confirmed(item) { this.options.confirmed(item); this.hide(); - }; - SimpleSelectListView.prototype.getFilterKey = function () { + } + 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 () { + } + hide() { this.panel.hide(); this.restoreFocus(); - }; - SimpleSelectListView.prototype.cancelled = function () { + } + cancelled() { this.hide(); - }; - return SimpleSelectListView; -}(sp.SelectListView)); + } +} exports.SimpleSelectListView = SimpleSelectListView; diff --git a/dist/main/atom/views/tooltipView.js b/dist/main/atom/views/tooltipView.js index 153c2335f..eaf8f779e 100644 --- a/dist/main/atom/views/tooltipView.js +++ b/dist/main/atom/views/tooltipView.js @@ -1,28 +1,24 @@ "use strict"; -var tslib_1 = require("tslib"); -var view = require("./view"); +const view = require("./view"); var $ = view.$; -var TooltipView = (function (_super) { - tslib_1.__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; @@ -37,8 +33,7 @@ var TooltipView = (function (_super) { 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; diff --git a/dist/main/atom/views/typeOverlayView.js b/dist/main/atom/views/typeOverlayView.js index 8fd6d6830..c9d0138f2 100644 --- a/dist/main/atom/views/typeOverlayView.js +++ b/dist/main/atom/views/typeOverlayView.js @@ -1,11 +1,18 @@ "use strict"; -var escapeHtml = require("escape-html"); +const escapeHtml = require("escape-html"); function create(type, comment) { - var overlayHTML = "\n " + escapeHtml(type) + "\n "; + let overlayHTML = ` + ${escapeHtml(type)} + `; if (comment) { - overlayHTML += "\n
    \n
    \n " + escapeHtml(comment).replace(/(?:\r\n|\r|\n)/g, '
    ') + "\n
    \n "; + overlayHTML += ` +
    +
    + ${escapeHtml(comment).replace(/(?:\r\n|\r|\n)/g, '
    ')} +
    + `; } - var overlay = document.createElement('div'); + const overlay = document.createElement('div'); overlay.className = 'atomts-show-type-view'; overlay.innerHTML = overlayHTML; return overlay; diff --git a/dist/main/atom/views/view.js b/dist/main/atom/views/view.js index 38eb597f0..c5d4ec88f 100644 --- a/dist/main/atom/views/view.js +++ b/dist/main/atom/views/view.js @@ -1,48 +1,33 @@ "use strict"; -var tslib_1 = require("tslib"); -var sp = require("atom-space-pen-views"); -var View = (function (_super) { - tslib_1.__extends(View, _super); - function View(options) { - var _this = _super.call(this) || this; - _this.options = options; - _this.init(); - return _this; +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) { - tslib_1.__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; diff --git a/dist/main/atomts.js b/dist/main/atomts.js index f49a17ba2..52c0ed675 100644 --- a/dist/main/atomts.js +++ b/dist/main/atomts.js @@ -1,180 +1,159 @@ "use strict"; -var tslib_1 = require("tslib"); +const tslib_1 = require("tslib"); console.log("be initializing them package"); console.profile("atomts init"); -var startTime = process.hrtime(); -var _atom = require("atom"); -var atom_space_pen_views_1 = require("atom-space-pen-views"); -var mainPanelView_1 = require("./atom/views/mainPanelView"); -var fileStatusCache_1 = require("./atom/fileStatusCache"); -var _ = require("lodash"); -var hyperclickProvider = require("../hyperclickProvider"); -var atomConfig = require("./atom/atomConfig"); -var atomUtils = require("./atom/atomUtils"); -var autoCompleteProvider = require("./atom/autoCompleteProvider"); -var commands = require("./atom/commands/commands"); -var documentationView = require("./atom/views/documentationView"); -var fs = require("fs"); -var mainPanelView = require("./atom/views/mainPanelView"); -var path = require("path"); -var renameView = require("./atom/views/renameView"); -var tooltipManager = require("./atom/tooltipManager"); -var statusBarMessage; -var editorWatch; -var autoCompleteWatch; -var parent = require("../worker/parent"); +const startTime = process.hrtime(); +const atom_space_pen_views_1 = require("atom-space-pen-views"); +const lodash_1 = require("lodash"); +const clientResolver_1 = require("../client/clientResolver"); +const fileStatusCache_1 = require("./atom/fileStatusCache"); +const atomConfig = require("./atom/atomConfig"); +const atomUtils = require("./atom/atomUtils"); +const autoCompleteProvider = require("./atom/autoCompleteProvider"); +const commands = require("./atom/commands/commands"); +const fs = require("fs"); +const hyperclickProvider = require("../hyperclickProvider"); +const mainPanel = require("../main/atom/views/mainPanelView"); +const mainPanelView = require("./atom/views/mainPanelView"); +const path = require("path"); +const renameView = require("./atom/views/renameView"); +const tooltipManager = require("./atom/tooltipManager"); +const tsconfig = require("tsconfig/dist/tsconfig"); +const error_pusher_1 = require("./error_pusher"); +exports.clientResolver = new clientResolver_1.ClientResolver(); exports.config = atomConfig.schema; -var utils_1 = require("./lang/utils"); -var linter; -var hideIfNotActiveOnStart = utils_1.debounce(function () { +let linter; +let errorPusher; +let statusBarMessage; +let editorWatch; +let autoCompleteWatch; +exports.clientResolver.on("pendingRequestsChange", () => { + if (!mainPanel.panelView) + return; + const pending = Object.keys(exports.clientResolver.clients) + .map(serverPath => exports.clientResolver.clients[serverPath].pending); + mainPanel.panelView.updatePendingRequests([].concat.apply([], pending)); +}); +var hideIfNotActiveOnStart = lodash_1.debounce(() => { var editor = atom.workspace.getActiveTextEditor(); if (!atomUtils.onDiskAndTsRelated(editor)) { mainPanelView.hide(); } }, 100); -var attachViews = _.once(function () { - mainPanelView.attach(); - documentationView.attach(); - renameView.attach(); -}); -function readyToActivate() { - atom.workspace.onDidChangeActivePaneItem(function (editor) { - if (atomUtils.onDiskAndTs(editor)) { - var filePath = editor.getPath(); - attachViews(); - updatePanelConfig(filePath); - mainPanelView.panelView.updateFileStatus(filePath); - mainPanelView.show(); - } - else if (atomUtils.onDiskAndTsRelated(editor)) { - mainPanelView.show(); - } - else { - mainPanelView.hide(); +function activate(state) { + console.log("activating them package", state); + require('atom-package-deps').install('atom-typescript').then(() => { + if (linter) { + errorPusher = new error_pusher_1.ErrorPusher(linter); + exports.clientResolver.on("diagnostics", ({ type, serverPath, filePath, diagnostics }) => { + errorPusher.addErrors(type + serverPath, filePath, diagnostics); + }); } - }); - editorWatch = atom.workspace.observeTextEditors(function (editor) { - return tslib_1.__awaiter(this, void 0, void 0, function () { - var filePath, client, editorView, ext, unsubSyntax_1, unsubSemantic_1, onDisk, changeObserver, fasterChangeObserver, saveObserver, destroyObserver; - return tslib_1.__generator(this, function (_a) { - switch (_a.label) { - case 0: - filePath = editor.getPath(); - console.log("opened editor", filePath); - return [4 /*yield*/, parent.clients.get(filePath)]; - case 1: - client = _a.sent(); - console.log("found client for editor", { filePath: filePath, client: client }); - editorView = atom_space_pen_views_1.$(atom.views.getView(editor)); - tooltipManager.attach(editorView, editor); - ext = path.extname(filePath); - if (atomUtils.isAllowedExtension(ext)) { - unsubSyntax_1 = client.on("syntaxDiag", function (diag) { + mainPanelView.attach(); + renameView.attach(); + atom.workspace.onDidChangeActivePaneItem((editor) => { + console.log("did change active panel", editor); + if (atomUtils.onDiskAndTs(editor)) { + var filePath = editor.getPath(); + updatePanelConfig(filePath); + mainPanelView.panelView.updateFileStatus(filePath); + mainPanelView.show(); + } + else if (atomUtils.onDiskAndTsRelated(editor)) { + mainPanelView.show(); + } + else { + mainPanelView.hide(); + } + }); + editorWatch = atom.workspace.observeTextEditors(function (editor) { + return tslib_1.__awaiter(this, void 0, void 0, function* () { + let filePath = editor.getPath(); + console.log("opened editor", filePath); + let client = yield exports.clientResolver.get(filePath); + console.log("found client for editor", { filePath, client }); + var editorView = atom_space_pen_views_1.$(atom.views.getView(editor)); + tooltipManager.attach(editorView, editor); + var ext = path.extname(filePath); + if (atomUtils.isAllowedExtension(ext)) { + try { + client.executeOpen({ + file: filePath, + fileContent: editor.getText() + }); + updatePanelConfig(filePath); + var onDisk = false; + if (fs.existsSync(filePath)) { + onDisk = true; + } + hideIfNotActiveOnStart(); + if (onDisk) { + client.executeGetErr({ files: [filePath], delay: 100 }); + } + var changeObserver = editor.onDidStopChanging(() => { + if (editor === atom.workspace.getActiveTextEditor()) { + let status = fileStatusCache_1.getFileStatus(filePath); + status.modified = editor.isModified(); + mainPanelView.panelView.updateFileStatus(filePath); + } + if (!onDisk) { + console.log("file is not on disk.."); + return; + } + client.executeGetErr({ files: [filePath], delay: 100 }); + }); + var fasterChangeObserver = editor.buffer.onDidChange((diff) => { + client.executeChange({ + endLine: diff.oldRange.end.row + 1, + endOffset: diff.oldRange.end.column + 1, + file: editor.getPath(), + line: diff.oldRange.start.row + 1, + offset: diff.oldRange.start.column + 1, + insertString: diff.newText, }); - unsubSemantic_1 = client.on("semanticDiag", function (diag) { - if (diag.file === filePath) { - console.log("semantic errors", diag); - mainPanelView_1.errorView.setErrors(filePath, diag.diagnostics.map(function (error) { - var preview = editor.buffer.getTextInRange(new _atom.Range([error.start.line - 1, error.start.offset - 1], [error.end.line - 1, error.end.offset - 1])); - return { - filePath: filePath, - startPos: { line: error.start.line - 1, col: error.start.offset - 1 }, - endPos: { line: error.end.line - 1, col: error.end.offset - 1 }, - message: error.text, - preview: preview - }; - })); + }); + var saveObserver = editor.onDidSave(function (event) { + return tslib_1.__awaiter(this, void 0, void 0, function* () { + console.log("saved", editor.getPath()); + onDisk = true; + if (filePath !== event.path) { + console.log("file path changed to", event.path); + client = yield exports.clientResolver.get(event.path); } + filePath = event.path; }); - try { - attachViews(); - client.executeOpen({ - file: filePath, - fileContent: editor.getText() - }); - updatePanelConfig(filePath); - onDisk = false; - if (fs.existsSync(filePath)) { - onDisk = true; - } - hideIfNotActiveOnStart(); - if (onDisk) { - client.executeGetErr({ files: [filePath], delay: 100 }); - } - 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; - } - client.executeGetErr({ files: [filePath], delay: 100 }); - }); - fasterChangeObserver = editor.buffer.onDidChange(function (diff) { - client.executeChange({ - endLine: diff.oldRange.end.row + 1, - endOffset: diff.oldRange.end.column + 1, - file: editor.getPath(), - line: diff.oldRange.start.row + 1, - offset: diff.oldRange.start.column + 1, - insertString: diff.newText, - }); - }); - saveObserver = editor.onDidSave(function (event) { - console.log("saved", editor.getPath()); - onDisk = true; - filePath = event.path; - }); - destroyObserver = editor.onDidDestroy(function () { - client.executeClose({ file: editor.getPath() }); - mainPanelView_1.errorView.setErrors(filePath, []); - changeObserver.dispose(); - fasterChangeObserver.dispose(); - saveObserver.dispose(); - destroyObserver.dispose(); - unsubSemantic_1(); - unsubSyntax_1(); - }); - } - catch (ex) { - console.error('Solve this in atom-typescript', ex); - throw ex; - } - } - return [2 /*return*/]; + }); + var destroyObserver = editor.onDidDestroy(() => { + client.executeClose({ file: editor.getPath() }); + changeObserver.dispose(); + fasterChangeObserver.dispose(); + saveObserver.dispose(); + destroyObserver.dispose(); + }); + } + catch (ex) { + console.error('Solve this in atom-typescript', ex); + throw ex; + } } }); }); + commands.registerCommands(); }); - commands.registerCommands(); } +exports.activate = activate; function updatePanelConfig(filePath) { - parent.clients.get(filePath).then(function (client) { + exports.clientResolver.get(filePath).then(client => { client.executeProjectInfo({ needFileNameList: false, file: filePath - }).then(function (result) { + }).then(result => { mainPanelView.panelView.setTsconfigInUse(result.body.configFileName); - }, function (err) { + }, err => { mainPanelView.panelView.setTsconfigInUse(''); }); }); } -function activate(state) { - console.log("activating them package", state); - atom.workspace.observeTextEditors(function (editor) { - console.log("opened editor", editor); - editor.observeGrammar(function (grammar) { - console.log("observed grammar", grammar); - }); - }); - require('atom-package-deps').install('atom-typescript').then(readyToActivate); -} -exports.activate = activate; function deactivate() { if (statusBarMessage) statusBarMessage.destroy(); @@ -189,11 +168,11 @@ function serialize() { } exports.serialize = serialize; function consumeLinter(registry) { - console.log("consume this"); + console.log("consume linter"); linter = registry.register({ - name: "Typescript" + name: "" }); - console.log("got linter", linter); + console.log("linter is", linter); } exports.consumeLinter = consumeLinter; function provide() { @@ -204,5 +183,13 @@ function getHyperclickProvider() { return hyperclickProvider; } exports.getHyperclickProvider = getHyperclickProvider; +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.loadProjectConfig = loadProjectConfig; console.profileEnd(); console.log("init took", process.hrtime(startTime)); diff --git a/dist/main/error_pusher.js b/dist/main/error_pusher.js new file mode 100644 index 000000000..d71785df3 --- /dev/null +++ b/dist/main/error_pusher.js @@ -0,0 +1,38 @@ +"use strict"; +const lodash_1 = require("lodash"); +const tsUtil_1 = require("./utils/tsUtil"); +class ErrorPusher { + constructor(linter) { + this.errors = new Map(); + this.pushErrors = lodash_1.debounce(() => { + const errors = []; + for (const fileErrors of this.errors.values()) { + for (const [filePath, diagnostics] of fileErrors) { + for (const diagnostic of diagnostics) { + errors.push({ + type: "Error", + text: diagnostic.text, + filePath: filePath, + range: diagnostic.start ? tsUtil_1.locationsToRange(diagnostic.start, diagnostic.end) : undefined + }); + } + } + } + this.linter.setMessages(errors); + }, 100); + this.linter = linter; + } + addErrors(prefix, filePath, errors) { + let prefixed = this.errors.get(prefix); + if (!prefixed) { + prefixed = new Map(); + this.errors.set(prefix, prefixed); + } + prefixed.set(filePath, errors); + this.pushErrors(); + } + clear() { + console.log("clearing errors"); + } +} +exports.ErrorPusher = ErrorPusher; 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/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/utils.js b/dist/main/lang/utils.js index c63a10752..1ca897637 100644 --- a/dist/main/lang/utils.js +++ b/dist/main/lang/utils.js @@ -1,19 +1,15 @@ 'use strict'; -var path = require("path"); +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]; - } +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); @@ -25,7 +21,7 @@ function clone(target) { } exports.clone = clone; function createMap(arr) { - return arr.reduce(function (result, key) { + return arr.reduce((result, key) => { result[key] = true; return result; }, {}); @@ -37,13 +33,12 @@ function pathResolve(from, to) { return result.slice(index); } exports.pathResolve = pathResolve; -var Signal = (function () { - function Signal() { +class Signal { + constructor() { this.listeners = []; this.priorities = []; } - Signal.prototype.add = function (listener, priority) { - if (priority === void 0) { priority = 0; } + add(listener, priority = 0) { var index = this.listeners.indexOf(listener); if (index !== -1) { this.priorities[index] = priority; @@ -58,30 +53,29 @@ var Signal = (function () { } this.priorities.push(priority); this.listeners.push(listener); - }; - Signal.prototype.remove = function (listener) { + } + remove(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) { + } + dispatch(parameter) { + var hasBeenCanceled = this.listeners.every((listener) => { var result = listener(parameter); return result !== false; }); return hasBeenCanceled; - }; - Signal.prototype.clear = function () { + } + clear() { this.listeners = []; this.priorities = []; - }; - Signal.prototype.hasListeners = function () { + } + hasListeners() { return this.listeners.length > 0; - }; - return Signal; -}()); + } +} exports.Signal = Signal; function binarySearch(array, value) { var low = 0; @@ -118,37 +112,34 @@ function pathIsRelative(str) { return str[0] == '.' || str.substring(0, 2) == "./" || str.substring(0, 3) == "../"; } exports.pathIsRelative = pathIsRelative; -var Dict = (function () { - function Dict() { +class Dict { + constructor() { this.table = Object.create(null); } - Dict.prototype.setValue = function (key, item) { + setValue(key, item) { this.table[key] = item; - }; - Dict.prototype.getValue = function (key) { return this.table[key]; }; - Dict.prototype.clearValue = function (key) { + } + getValue(key) { return this.table[key]; } + clearValue(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 () { + } + clearAll() { this.table = Object.create(null); } + keys() { return Object.keys(this.table); } + values() { 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; } +function delay(seconds = 2) { delayMilliseconds(seconds * 1000); } exports.delay = delay; ; -function delayMilliseconds(milliseconds) { - if (milliseconds === void 0) { milliseconds = 100; } +function delayMilliseconds(milliseconds = 100) { var d1 = new Date(); var d2 = new Date(); while (d2.valueOf() < d1.valueOf() + milliseconds) { @@ -157,9 +148,8 @@ function delayMilliseconds(milliseconds) { } exports.delayMilliseconds = delayMilliseconds; ; -var now = function () { return new Date().getTime(); }; -function debounce(func, milliseconds, immediate) { - if (immediate === void 0) { immediate = false; } +var now = () => new Date().getTime(); +function debounce(func, milliseconds, immediate = false) { var timeout, args, context, timestamp, result; var wait = milliseconds; var later = function () { @@ -193,7 +183,7 @@ function debounce(func, milliseconds, immediate) { exports.debounce = debounce; ; var punctuations = createMap([';', '{', '}', '(', ')', '.', ':', '<', '>', "'", '"']); -exports.prefixEndsInPunctuation = function (prefix) { return prefix.length && prefix.trim().length && punctuations[prefix.trim()[prefix.trim().length - 1]]; }; +exports.prefixEndsInPunctuation = (prefix) => prefix.length && prefix.trim().length && punctuations[prefix.trim()[prefix.trim().length - 1]]; var nameExtractorRegex = /return (.*);/; function getName(nameLambda) { var m = nameExtractorRegex.exec(nameLambda + ""); diff --git a/dist/main/tsconfig/formatting.js b/dist/main/tsconfig/formatting.js index 29fa22f8e..85c9afd68 100644 --- a/dist/main/tsconfig/formatting.js +++ b/dist/main/tsconfig/formatting.js @@ -1,5 +1,5 @@ "use strict"; -var os_1 = require("os"); +const os_1 = require("os"); function defaultFormatCodeOptions() { return { baseIndentSize: 4, diff --git a/dist/main/utils/fsUtil.js b/dist/main/utils/fsUtil.js index 69cfb6d28..2669fcce8 100644 --- a/dist/main/utils/fsUtil.js +++ b/dist/main/utils/fsUtil.js @@ -3,13 +3,9 @@ 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)); +const path = require("path"); +function resolve(...args) { + return consistentPath(path.resolve(...args)); } exports.resolve = resolve; function isExt(path, ext) { diff --git a/dist/main/utils/tsUtil.js b/dist/main/utils/tsUtil.js new file mode 100644 index 000000000..fe4b817c3 --- /dev/null +++ b/dist/main/utils/tsUtil.js @@ -0,0 +1,14 @@ +"use strict"; +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; diff --git a/dist/worker/debug.js b/dist/worker/debug.js deleted file mode 100644 index 8319ccdba..000000000 --- a/dist/worker/debug.js +++ /dev/null @@ -1,3 +0,0 @@ -"use strict"; -exports.debugAll = true; -exports.debugSync = false; diff --git a/dist/worker/parent.js b/dist/worker/parent.js deleted file mode 100644 index 53496ec7f..000000000 --- a/dist/worker/parent.js +++ /dev/null @@ -1,20 +0,0 @@ -"use strict"; -var clientResolver_1 = require("../client/clientResolver"); -var mainPanel = require("../main/atom/views/mainPanelView"); -var tsconfig = require("tsconfig/dist/tsconfig"); -exports.clients = new clientResolver_1.ClientResolver(); -exports.clients.on("pendingRequestsChange", function () { - if (!mainPanel.panelView) - return; - var pending = Object.keys(exports.clients.clients) - .map(function (serverPath) { return exports.clients.clients[serverPath].pending; }); - mainPanel.panelView.updatePendingRequests([].concat.apply([], pending)); -}); -function loadProjectConfig(sourcePath) { - return exports.clients.get(sourcePath).then(function (client) { - return client.executeProjectInfo({ needFileNameList: false, file: sourcePath }).then(function (result) { - return tsconfig.load(result.body.configFileName); - }); - }); -} -exports.loadProjectConfig = loadProjectConfig; diff --git a/lib/client/client.ts b/lib/client/client.ts index f39f9b1e2..4f6772983 100644 --- a/lib/client/client.ts +++ b/lib/client/client.ts @@ -52,6 +52,9 @@ export class TypescriptServiceClient { executeGetErr(args: protocol.GeterrRequestArgs) { this.execute("geterr", args) } + executeGetErrForProject(args: protocol.GeterrForProjectRequestArgs) { + this.execute("geterrForProject", args) + } executeOpen(args: protocol.OpenRequestArgs) { this.execute("open", args) } @@ -73,6 +76,7 @@ export class TypescriptServiceClient { } /** 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 diff --git a/lib/client/clientResolver.ts b/lib/client/clientResolver.ts index 32a2cb7a5..80ca9319d 100644 --- a/lib/client/clientResolver.ts +++ b/lib/client/clientResolver.ts @@ -2,6 +2,16 @@ import {TypescriptServiceClient as Client} from "./client" import * as events from "events" import * as path from "path" import * as nodeResolve from "resolve" +import {Diagnostic, DiagnosticEventBody} from "typescript/lib/protocol" + +type DiagnosticTypes = "configFileDiag" | "semanticDiag" | "syntaxDiag" + +interface DiagnosticsPayload { + diagnostics: Diagnostic[] + filePath: string, + serverPath: string, + type: DiagnosticTypes, +} const defaultServerPath = require.resolve("typescript/bin/tsserver") @@ -18,6 +28,13 @@ export class ClientResolver extends events.EventEmitter { } } = {} + // 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(() => defaultServerPath) @@ -38,6 +55,19 @@ export class ClientResolver extends events.EventEmitter { this.emit("pendingRequestsChange") }) + const diagnosticHandler = (type: string, result: DiagnosticEventBody) => { + this.emit("diagnostics", { + type, + serverPath, + filePath: result.file, + 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 }) } diff --git a/lib/main/atom/autoCompleteProvider.ts b/lib/main/atom/autoCompleteProvider.ts index 78cb7b296..d86b344d4 100644 --- a/lib/main/atom/autoCompleteProvider.ts +++ b/lib/main/atom/autoCompleteProvider.ts @@ -3,7 +3,7 @@ import atomUtils = require('./atomUtils') import fs = require('fs') -import parent = require('../../worker/parent') +import {clientResolver} from "../atomts" declare module autocompleteplus { /** What gets passed into the handler */ @@ -63,7 +63,7 @@ export var provider: autocompleteplus.Provider = { if (!filePath || !fs.existsSync(filePath)) return []; - const client = await parent.clients.get(filePath) + const client = await clientResolver.get(filePath) // var {isReference, isRequire, isImport} = getModuleAutocompleteType(options.scopeDescriptor.scopes) // @@ -153,6 +153,6 @@ export var provider: autocompleteplus.Provider = { }; // } }); - }); + }).catch(() => []) }, } diff --git a/lib/main/atom/commands/commands.ts b/lib/main/atom/commands/commands.ts index 935a62331..22f860f3a 100644 --- a/lib/main/atom/commands/commands.ts +++ b/lib/main/atom/commands/commands.ts @@ -1,4 +1,4 @@ -import parent = require("../../../worker/parent"); +import {clientResolver} from "../../atomts" import atomUtils = require("../atomUtils"); import autoCompleteProvider = require("../autoCompleteProvider"); // import path = require('path'); @@ -170,7 +170,7 @@ export function registerCommands() { var position = cursor.getBufferPosition() var filePath = editor.getPath(); - parent.clients.get(filePath).then(client => { + clientResolver.get(filePath).then(client => { return client.executeQuickInfo({ file: filePath, line: position.row+1, diff --git a/lib/main/atom/tooltipManager.ts b/lib/main/atom/tooltipManager.ts index ab827f741..2ae65d268 100644 --- a/lib/main/atom/tooltipManager.ts +++ b/lib/main/atom/tooltipManager.ts @@ -1,10 +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 {clientResolver} from "../atomts" import path = require('path'); import fs = require('fs'); @@ -35,7 +33,7 @@ export function attach(editorView: JQuery, editor: AtomCore.IEditor) { return; } - var clientPromise = parent.clients.get(filePath) + var clientPromise = clientResolver.get(filePath) var scroll = getFromShadowDom(editorView, '.scroll-view'); var subscriber = new Subscriber(); var exprTypeTimeout = null; @@ -97,10 +95,7 @@ export function attach(editorView: JQuery, editor: AtomCore.IEditor) { if (documentation) { message = message + `
    ${escape(documentation).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); - } + exprTypeTooltip.updateText(message); }, () => { /* ignore the errors */ }) }) } 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/mainPanelView.ts b/lib/main/atom/views/mainPanelView.ts index d66a229ae..3471020a9 100644 --- a/lib/main/atom/views/mainPanelView.ts +++ b/lib/main/atom/views/mainPanelView.ts @@ -2,7 +2,6 @@ import view = require('./view'); import lineMessageView = require('./lineMessageView'); import atomUtils = require("../atomUtils"); -import * as utils from "../../lang/utils"; var panelHeaders = { error: 'Errors In Open Files', @@ -503,69 +502,3 @@ 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/atomts.ts b/lib/main/atomts.ts index ad5873a2f..081b035ad 100644 --- a/lib/main/atomts.ts +++ b/lib/main/atomts.ts @@ -3,39 +3,45 @@ console.profile("atomts init") const startTime = process.hrtime() -import _atom = require('atom') import {$} from "atom-space-pen-views" -import {errorView} from "./atom/views/mainPanelView" +import {debounce} from "lodash" +import {ClientResolver} from "../client/clientResolver" import {getFileStatus} from "./atom/fileStatusCache" -import * as _ from "lodash" +import * as atomConfig from './atom/atomConfig' +import * as atomUtils from './atom/atomUtils' +import * as autoCompleteProvider from './atom/autoCompleteProvider' +import * as commands from "./atom/commands/commands" +import * as fs from 'fs' import * as hyperclickProvider from "../hyperclickProvider" -import atomConfig = require('./atom/atomConfig') -import atomUtils = require('./atom/atomUtils') -import autoCompleteProvider = require('./atom/autoCompleteProvider') -import commands = require("./atom/commands/commands") -import documentationView = require('./atom/views/documentationView') -import fs = require('fs') -import mainPanelView = require("./atom/views/mainPanelView") -import path = require('path') -import renameView = require('./atom/views/renameView') -import tooltipManager = require('./atom/tooltipManager') +import * as mainPanel from "../main/atom/views/mainPanelView" +import * as mainPanelView from "./atom/views/mainPanelView" +import * as path from 'path' +import * as renameView from './atom/views/renameView' +import * as tooltipManager from './atom/tooltipManager' +import * as tsconfig from "tsconfig/dist/tsconfig" +import {LinterRegistry, Linter} from "../typings/linter" +import {ErrorPusher} from "./error_pusher" // globals -var statusBarMessage; -var editorWatch: AtomCore.Disposable; -var autoCompleteWatch: AtomCore.Disposable; - -export interface PackageState {} +export const clientResolver = new ClientResolver() +export const config = atomConfig.schema +let linter: Linter +let errorPusher: ErrorPusher +let statusBarMessage +let editorWatch: AtomCore.Disposable +let autoCompleteWatch: AtomCore.Disposable -import parent = require('../worker/parent'); +interface PackageState {} -// Export config -export var config = atomConfig.schema; -import {debounce} from "./lang/utils"; +clientResolver.on("pendingRequestsChange", () => { + // We only start once the panel view is initialized + if (!mainPanel.panelView) return; -import {LinterRegistry, Linter} from "../linter" + const pending = Object.keys(clientResolver.clients) + .map(serverPath => clientResolver.clients[serverPath].pending) -let linter: Linter + mainPanel.panelView.updatePendingRequests([].concat.apply([], pending)) +}) var hideIfNotActiveOnStart = debounce(() => { // Only show if this editor is active: @@ -45,36 +51,33 @@ var hideIfNotActiveOnStart = debounce(() => { } }, 100); -const attachViews = _.once(() => { - mainPanelView.attach(); +export function activate(state: PackageState) { + console.log("activating them package", state) + + require('atom-package-deps').install('atom-typescript').then(() => { + + if (linter) { + errorPusher = new ErrorPusher(linter) - // Add the documentation view - documentationView.attach(); + clientResolver.on("diagnostics", ({type, serverPath, filePath, diagnostics}) => { + errorPusher.addErrors(type + serverPath, filePath, diagnostics) + }) + } + + mainPanelView.attach(); // Add the rename view renameView.attach(); -}) - -/** only called once we have our dependencies */ -function readyToActivate() { // Observe changed active editor atom.workspace.onDidChangeActivePaneItem((editor: AtomCore.IEditor) => { + console.log("did change active panel", editor) + if (atomUtils.onDiskAndTs(editor)) { var filePath = editor.getPath(); - attachViews() updatePanelConfig(filePath); - // // 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(); } @@ -91,7 +94,7 @@ function readyToActivate() { let filePath = editor.getPath() console.log("opened editor", filePath) - let client = await parent.clients.get(filePath) + let client = await clientResolver.get(filePath) console.log("found client for editor", {filePath, client}) // subscribe for tooltips @@ -101,40 +104,7 @@ function readyToActivate() { var ext = path.extname(filePath); if (atomUtils.isAllowedExtension(ext)) { - - // Listen for error events for this file and display them - const unsubSyntax = client.on("syntaxDiag", diag => { - // console.log("syntax errors", diag) - }) - - const unsubSemantic = client.on("semanticDiag", diag => { - if (diag.file === filePath) { - console.log("semantic errors", diag) - - errorView.setErrors(filePath, diag.diagnostics.map(error => { - const preview = editor.buffer.getTextInRange( - new _atom.Range( - [error.start.line-1, error.start.offset-1], - [error.end.line-1, error.end.offset-1])) - - return { - filePath: filePath, - startPos: {line: error.start.line - 1, col: error.start.offset - 1}, - endPos: {line: error.end.line - 1, col: error.end.offset - 1}, - message: error.text, - preview - } - - - })) - } - }) - - try { - // Only once stuff - attachViews() - client.executeOpen({ file: filePath, fileContent: editor.getText() @@ -186,11 +156,8 @@ function readyToActivate() { // 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; + console.log("file is not on disk..") + return } // Set errors in project per file @@ -240,29 +207,30 @@ function readyToActivate() { }); // Observe editors saving - var saveObserver = editor.onDidSave((event) => { + var saveObserver = editor.onDidSave(async function(event) { console.log("saved", editor.getPath()) - onDisk = true; + + 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 }); + + if (filePath !== event.path) { + console.log("file path changed to", event.path) + client = await clientResolver.get(event.path) + } + + filePath = event.path }); // Observe editors closing var destroyObserver = editor.onDidDestroy(() => { client.executeClose({file: editor.getPath()}) - // Clear errors in view - errorView.setErrors(filePath, []); - // Clear editor observers changeObserver.dispose(); fasterChangeObserver.dispose(); saveObserver.dispose(); destroyObserver.dispose(); - unsubSemantic() - unsubSyntax() }); } catch (ex) { @@ -274,11 +242,13 @@ function readyToActivate() { // Register the commands commands.registerCommands(); + + }) } /** Update the panel with the configu resolved from the given source file */ function updatePanelConfig(filePath: string) { - parent.clients.get(filePath).then(client => { + clientResolver.get(filePath).then(client => { client.executeProjectInfo({ needFileNameList: false, file: filePath @@ -290,20 +260,6 @@ function updatePanelConfig(filePath: string) { }) } -export function activate(state: PackageState) { - console.log("activating them package", state) - - atom.workspace.observeTextEditors(function(editor){ - console.log("opened editor", editor) - - editor.observeGrammar(function(grammar) { - console.log("observed grammar", grammar) - }) - }) - - require('atom-package-deps').install('atom-typescript').then(readyToActivate) -} - export function deactivate() { if (statusBarMessage) statusBarMessage.destroy(); if (editorWatch) editorWatch.dispose(); @@ -315,13 +271,13 @@ export function serialize(): PackageState { } export function consumeLinter(registry: LinterRegistry) { - console.log("consume this") + console.log("consume linter") linter = registry.register({ - name: "Typescript" + name: "" }) - console.log("got linter", linter) + console.log("linter is", linter) } // Registering an autocomplete provider @@ -333,5 +289,13 @@ export function getHyperclickProvider() { return hyperclickProvider; } +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) + }) + }) +} + console.profileEnd() console.log("init took", process.hrtime(startTime)) diff --git a/lib/main/error_pusher.ts b/lib/main/error_pusher.ts new file mode 100644 index 000000000..97115d622 --- /dev/null +++ b/lib/main/error_pusher.ts @@ -0,0 +1,57 @@ +import {debounce} from "lodash" +import {Diagnostic} from "typescript/lib/protocol" +import {Linter, LinterMessage} from "../typings/linter" +import {locationsToRange} from "./utils/tsUtil" + +/** Class that collects errors from all of the clients and pushes them to the Linter service */ +export class ErrorPusher { + linter: Linter + + private errors: Map> = new Map() + + constructor(linter: Linter) { + this.linter = linter + } + + /** Add errors. Previous errors with the same prefix and filePath are going to be replaced */ + addErrors(prefix: string, filePath: string, errors: Diagnostic[]) { + let prefixed = this.errors.get(prefix) + if (!prefixed) { + prefixed = new Map() + this.errors.set(prefix, prefixed) + } + + prefixed.set(filePath, errors) + + this.pushErrors() + } + + /** Clear all errors */ + clear() { + console.log("clearing errors") + } + + private pushErrors = debounce(() => { + const errors: LinterMessage[] = [] + + for (const fileErrors of this.errors.values()) { + for (const [filePath, diagnostics] of fileErrors) { + for (const diagnostic of diagnostics) { + errors.push({ + type: "Error", + text: diagnostic.text, + filePath: filePath, + range: diagnostic.start ? locationsToRange(diagnostic.start, diagnostic.end) : undefined + }) + } + } + } + + this.linter.setMessages(errors) + + }, 100) +} + +// function rangeFromTS(start: protocol.): atom.Range { +// +// } diff --git a/lib/main/utils/tsUtil.ts b/lib/main/utils/tsUtil.ts new file mode 100644 index 000000000..1213d91b4 --- /dev/null +++ b/lib/main/utils/tsUtil.ts @@ -0,0 +1,14 @@ +import {Location, TextSpan} from "typescript/lib/protocol" +import {Point, Range} from "atom" + +export function locationToPoint(loc: Location): 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, end): TextBuffer.IRange { + return new Range(locationToPoint(start), locationToPoint(end)) +} diff --git a/lib/tsconfig.json b/lib/tsconfig.json index 7fe45d27f..e56ec8774 100644 --- a/lib/tsconfig.json +++ b/lib/tsconfig.json @@ -1,6 +1,6 @@ { "compilerOptions": { - "target": "es5", + "target": "es6", "module": "commonjs", "declaration": false, "lib": ["es6", "dom"], @@ -15,9 +15,6 @@ "jsx": "react", "types": [] }, - "dts": { - "name": "atom-typescript" - }, "atom": { "formatOnSave": false } diff --git a/lib/linter.ts b/lib/typings/linter.d.ts similarity index 90% rename from lib/linter.ts rename to lib/typings/linter.d.ts index cba9a290f..efab4d130 100644 --- a/lib/linter.ts +++ b/lib/typings/linter.d.ts @@ -1,6 +1,6 @@ export interface Linter { deleteMessages() - sendMessages(messages: LinterMessage[]) + setMessages(messages: LinterMessage[]) dispose() } @@ -19,4 +19,4 @@ export interface LinterMessage { export interface LinterRegistry { register(config: LinterConfig): Linter -} \ No newline at end of file +} diff --git a/lib/globals.ts b/lib/typings/typings.d.ts similarity index 100% rename from lib/globals.ts rename to lib/typings/typings.d.ts diff --git a/lib/worker/parent.ts b/lib/worker/parent.ts deleted file mode 100644 index 94a689888..000000000 --- a/lib/worker/parent.ts +++ /dev/null @@ -1,23 +0,0 @@ -import {ClientResolver} from "../client/clientResolver" -import * as mainPanel from "../main/atom/views/mainPanelView" -import * as tsconfig from "tsconfig/dist/tsconfig" - -export const clients = new ClientResolver() - -clients.on("pendingRequestsChange", () => { - // We only start once the panel view is initialized - if (!mainPanel.panelView) return; - - const pending = Object.keys(clients.clients) - .map(serverPath => clients.clients[serverPath].pending) - - mainPanel.panelView.updatePendingRequests([].concat.apply([], pending)) -}) - -export function loadProjectConfig(sourcePath: string): Promise { - return clients.get(sourcePath).then(client => { - return client.executeProjectInfo({needFileNameList: false, file: sourcePath}).then(result => { - return tsconfig.load(result.body.configFileName) - }) - }) -} diff --git a/package.json b/package.json index 97d82568f..18e4ed11b 100644 --- a/package.json +++ b/package.json @@ -4,7 +4,9 @@ "main": "./dist/main/atomts", "preferGlobal": true, "description": "The only TypeScript plugin you will ever need.", - "activationHooks": ["atom-typescript:grammar-used"], + "activationHooks": [ + "atom-typescript:grammar-used" + ], "scripts": { "build": "ts-node scripts/grammar.ts", "test": "tsc -p ./lib && tsc --noEmit -p ./scripts" @@ -44,6 +46,7 @@ "dependencies": { "@types/atom": "0.0.35", "@types/byline": "^4.2.31", + "@types/lodash": "4.14.41", "@types/resolve": "0.0.4", "atom-package-deps": "^2.0.3", "atom-space-pen-views": "^2.0.4", diff --git a/styles/atomts-grammar-syntax.less b/styles/atomts-grammar-syntax.less index c78013578..ef7402d33 100644 --- a/styles/atomts-grammar-syntax.less +++ b/styles/atomts-grammar-syntax.less @@ -1,4 +1,4 @@ -atom-text-editor::shadow { +atom-text-editor { .source.ts, .source.tsx { .require.path, .reference.path, .es6import.path, .amd.path { 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/tslint.json b/tslint.json new file mode 100644 index 000000000..0967ef424 --- /dev/null +++ b/tslint.json @@ -0,0 +1 @@ +{} From a6d9cdecf2a79a6a46fabb1b3e030257d25baab2 Mon Sep 17 00:00:00 2001 From: Guntars Asmanis-Graham Date: Sat, 3 Dec 2016 21:59:08 -0500 Subject: [PATCH 18/70] Highlight occurrences in the open file --- dist/client/client.js | 4 ++++ dist/main/atomts.js | 22 ++++++++++++++++++++++ lib/client/client.ts | 4 ++++ lib/main/atomts.ts | 26 ++++++++++++++++++++++++++ styles/highlights.less | 11 +++++++++++ 5 files changed, 67 insertions(+) create mode 100644 styles/highlights.less diff --git a/dist/client/client.js b/dist/client/client.js index 3c3243914..60b5c8b8f 100644 --- a/dist/client/client.js +++ b/dist/client/client.js @@ -45,6 +45,9 @@ class TypescriptServiceClient { executeGetErrForProject(args) { this.execute("geterrForProject", args); } + executeOccurances(args) { + return this.execute("occurrences", args); + } executeOpen(args) { this.execute("open", args); } @@ -134,6 +137,7 @@ class TypescriptServiceClient { exports.TypescriptServiceClient = TypescriptServiceClient; TypescriptServiceClient.commandWithResponse = { completions: true, + occurrences: true, projectInfo: true, quickinfo: true }; diff --git a/dist/main/atomts.js b/dist/main/atomts.js index 52c0ed675..70ced1f81 100644 --- a/dist/main/atomts.js +++ b/dist/main/atomts.js @@ -19,6 +19,7 @@ const path = require("path"); const renameView = require("./atom/views/renameView"); const tooltipManager = require("./atom/tooltipManager"); const tsconfig = require("tsconfig/dist/tsconfig"); +const tsUtil_1 = require("./utils/tsUtil"); const error_pusher_1 = require("./error_pusher"); exports.clientResolver = new clientResolver_1.ClientResolver(); exports.config = atomConfig.schema; @@ -90,6 +91,27 @@ function activate(state) { if (onDisk) { client.executeGetErr({ files: [filePath], delay: 100 }); } + const markers = []; + editor.onDidChangeCursorPosition(() => { + for (const marker of markers) { + marker.destroy(); + } + const pos = editor.getLastCursor().getBufferPosition(); + client.executeOccurances({ + file: filePath, + line: pos.row + 1, + offset: pos.column + 1 + }).then(result => { + for (const ref of result.body) { + const marker = editor.markBufferRange(tsUtil_1.spanToRange(ref)); + editor.decorateMarker(marker, { + type: "highlight", + class: "atom-typescript-occurrence" + }); + markers.push(marker); + } + }).catch(() => null); + }); var changeObserver = editor.onDidStopChanging(() => { if (editor === atom.workspace.getActiveTextEditor()) { let status = fileStatusCache_1.getFileStatus(filePath); diff --git a/lib/client/client.ts b/lib/client/client.ts index 4f6772983..ea43db9ee 100644 --- a/lib/client/client.ts +++ b/lib/client/client.ts @@ -36,6 +36,7 @@ export class TypescriptServiceClient { static commandWithResponse = { completions: true, + occurrences: true, projectInfo: true, quickinfo: true } @@ -55,6 +56,9 @@ export class TypescriptServiceClient { executeGetErrForProject(args: protocol.GeterrForProjectRequestArgs) { this.execute("geterrForProject", args) } + executeOccurances(args: protocol.FileLocationRequestArgs): Promise { + return this.execute("occurrences", args) + } executeOpen(args: protocol.OpenRequestArgs) { this.execute("open", args) } diff --git a/lib/main/atomts.ts b/lib/main/atomts.ts index 081b035ad..d5b3e7e3e 100644 --- a/lib/main/atomts.ts +++ b/lib/main/atomts.ts @@ -19,6 +19,7 @@ import * as path from 'path' import * as renameView from './atom/views/renameView' import * as tooltipManager from './atom/tooltipManager' import * as tsconfig from "tsconfig/dist/tsconfig" +import {spanToRange} from "./utils/tsUtil" import {LinterRegistry, Linter} from "../typings/linter" import {ErrorPusher} from "./error_pusher" @@ -143,6 +144,31 @@ export function activate(state: PackageState) { // }); } + const markers: AtomCore.IDisplayBufferMarker[] = [] + + editor.onDidChangeCursorPosition(() => { + for (const marker of markers) { + marker.destroy() + } + + const pos = editor.getLastCursor().getBufferPosition() + + client.executeOccurances({ + file: filePath, + line: pos.row+1, + offset: pos.column+1 + }).then(result => { + for (const ref of result.body) { + const marker = editor.markBufferRange(spanToRange(ref)) + editor.decorateMarker(marker as any, { + type: "highlight", + class: "atom-typescript-occurrence" + }) + markers.push(marker) + } + }).catch(() => null) + }) + // Observe editors changing var changeObserver = editor.onDidStopChanging(() => { diff --git a/styles/highlights.less b/styles/highlights.less new file mode 100644 index 000000000..db6615377 --- /dev/null +++ b/styles/highlights.less @@ -0,0 +1,11 @@ +@import "ui-variables"; + +atom-text-editor::shadow { + .highlights { + .atom-typescript-occurrence { + .region { + border-bottom: 1px solid @text-color; + } + } + } +} From b88e6adf91a3436ccbd4d915963ce5bdbf88dc35 Mon Sep 17 00:00:00 2001 From: Guntars Asmanis-Graham Date: Sun, 4 Dec 2016 02:22:16 -0500 Subject: [PATCH 19/70] Create TypescriptEditorPane --- dist/client/clientResolver.js | 5 +- dist/main/atomts.js | 186 ++++------------- dist/main/error_pusher.js | 15 +- dist/main/typescript_editor_pane.js | 133 ++++++++++++ lib/client/clientResolver.ts | 10 +- lib/main/atom/atomUtils.ts | 2 +- lib/main/atomts.ts | 304 ++++++---------------------- lib/main/error_pusher.ts | 24 +-- lib/main/typescript_editor_pane.ts | 178 ++++++++++++++++ lib/typings/atom.d.ts | 8 + lib/typings/atom_core.d.ts | 11 + 11 files changed, 465 insertions(+), 411 deletions(-) create mode 100644 dist/main/typescript_editor_pane.js create mode 100644 lib/main/typescript_editor_pane.ts create mode 100644 lib/typings/atom.d.ts create mode 100644 lib/typings/atom_core.d.ts diff --git a/dist/client/clientResolver.js b/dist/client/clientResolver.js index 9c603c859..965197519 100644 --- a/dist/client/clientResolver.js +++ b/dist/client/clientResolver.js @@ -33,7 +33,7 @@ class ClientResolver extends events.EventEmitter { this.emit("diagnostics", { type, serverPath, - filePath: result.file, + filePath: isConfDiagBody(result) ? result.configFile : result.file, diagnostics: result.diagnostics }); }; @@ -59,3 +59,6 @@ function resolveServer(sourcePath) { }); } exports.resolveServer = resolveServer; +function isConfDiagBody(body) { + return body && body.triggerFile && body.configFile; +} diff --git a/dist/main/atomts.js b/dist/main/atomts.js index 70ced1f81..2803ee480 100644 --- a/dist/main/atomts.js +++ b/dist/main/atomts.js @@ -1,33 +1,25 @@ "use strict"; -const tslib_1 = require("tslib"); console.log("be initializing them package"); console.profile("atomts init"); const startTime = process.hrtime(); -const atom_space_pen_views_1 = require("atom-space-pen-views"); -const lodash_1 = require("lodash"); const clientResolver_1 = require("../client/clientResolver"); -const fileStatusCache_1 = require("./atom/fileStatusCache"); +const atom_1 = require("atom"); +const lodash_1 = require("lodash"); +const error_pusher_1 = require("./error_pusher"); +const typescript_editor_pane_1 = require("./typescript_editor_pane"); const atomConfig = require("./atom/atomConfig"); -const atomUtils = require("./atom/atomUtils"); const autoCompleteProvider = require("./atom/autoCompleteProvider"); const commands = require("./atom/commands/commands"); -const fs = require("fs"); const hyperclickProvider = require("../hyperclickProvider"); const mainPanel = require("../main/atom/views/mainPanelView"); const mainPanelView = require("./atom/views/mainPanelView"); -const path = require("path"); const renameView = require("./atom/views/renameView"); -const tooltipManager = require("./atom/tooltipManager"); const tsconfig = require("tsconfig/dist/tsconfig"); -const tsUtil_1 = require("./utils/tsUtil"); -const error_pusher_1 = require("./error_pusher"); exports.clientResolver = new clientResolver_1.ClientResolver(); exports.config = atomConfig.schema; let linter; -let errorPusher; -let statusBarMessage; -let editorWatch; -let autoCompleteWatch; +const errorPusher = new error_pusher_1.ErrorPusher(); +const subscriptions = new atom_1.CompositeDisposable(); exports.clientResolver.on("pendingRequestsChange", () => { if (!mainPanel.panelView) return; @@ -35,154 +27,54 @@ exports.clientResolver.on("pendingRequestsChange", () => { .map(serverPath => exports.clientResolver.clients[serverPath].pending); mainPanel.panelView.updatePendingRequests([].concat.apply([], pending)); }); -var hideIfNotActiveOnStart = lodash_1.debounce(() => { - var editor = atom.workspace.getActiveTextEditor(); - if (!atomUtils.onDiskAndTsRelated(editor)) { - mainPanelView.hide(); - } -}, 100); function activate(state) { - console.log("activating them package", state); require('atom-package-deps').install('atom-typescript').then(() => { if (linter) { - errorPusher = new error_pusher_1.ErrorPusher(linter); + errorPusher.setLinter(linter); exports.clientResolver.on("diagnostics", ({ type, serverPath, filePath, diagnostics }) => { errorPusher.addErrors(type + serverPath, filePath, diagnostics); }); } mainPanelView.attach(); + mainPanelView.hide(); renameView.attach(); - atom.workspace.onDidChangeActivePaneItem((editor) => { - console.log("did change active panel", editor); - if (atomUtils.onDiskAndTs(editor)) { - var filePath = editor.getPath(); - updatePanelConfig(filePath); - mainPanelView.panelView.updateFileStatus(filePath); - mainPanelView.show(); - } - else if (atomUtils.onDiskAndTsRelated(editor)) { - mainPanelView.show(); - } - else { - mainPanelView.hide(); + commands.registerCommands(); + const panes = []; + const checkErrors = lodash_1.debounce((pane) => { + console.log("checking errors for all panes for", pane.filePath); + 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 typescript_editor_pane_1.TypescriptEditorPane(editor, { + checkErrors + })); + })); + let activePane = panes.find(pane => pane.editor === atom.workspace.getActiveTextEditor()); + if (activePane) { + activePane.onActivated(); + } + subscriptions.add(atom.workspace.onDidChangeActivePaneItem((editor) => { + if (activePane) { + activePane.onDeactivated(); + activePane = null; } - }); - editorWatch = atom.workspace.observeTextEditors(function (editor) { - return tslib_1.__awaiter(this, void 0, void 0, function* () { - let filePath = editor.getPath(); - console.log("opened editor", filePath); - let client = yield exports.clientResolver.get(filePath); - console.log("found client for editor", { filePath, client }); - var editorView = atom_space_pen_views_1.$(atom.views.getView(editor)); - tooltipManager.attach(editorView, editor); - var ext = path.extname(filePath); - if (atomUtils.isAllowedExtension(ext)) { - try { - client.executeOpen({ - file: filePath, - fileContent: editor.getText() - }); - updatePanelConfig(filePath); - var onDisk = false; - if (fs.existsSync(filePath)) { - onDisk = true; - } - hideIfNotActiveOnStart(); - if (onDisk) { - client.executeGetErr({ files: [filePath], delay: 100 }); - } - const markers = []; - editor.onDidChangeCursorPosition(() => { - for (const marker of markers) { - marker.destroy(); - } - const pos = editor.getLastCursor().getBufferPosition(); - client.executeOccurances({ - file: filePath, - line: pos.row + 1, - offset: pos.column + 1 - }).then(result => { - for (const ref of result.body) { - const marker = editor.markBufferRange(tsUtil_1.spanToRange(ref)); - editor.decorateMarker(marker, { - type: "highlight", - class: "atom-typescript-occurrence" - }); - markers.push(marker); - } - }).catch(() => null); - }); - var changeObserver = editor.onDidStopChanging(() => { - if (editor === atom.workspace.getActiveTextEditor()) { - let status = fileStatusCache_1.getFileStatus(filePath); - status.modified = editor.isModified(); - mainPanelView.panelView.updateFileStatus(filePath); - } - if (!onDisk) { - console.log("file is not on disk.."); - return; - } - client.executeGetErr({ files: [filePath], delay: 100 }); - }); - var fasterChangeObserver = editor.buffer.onDidChange((diff) => { - client.executeChange({ - endLine: diff.oldRange.end.row + 1, - endOffset: diff.oldRange.end.column + 1, - file: editor.getPath(), - line: diff.oldRange.start.row + 1, - offset: diff.oldRange.start.column + 1, - insertString: diff.newText, - }); - }); - var saveObserver = editor.onDidSave(function (event) { - return tslib_1.__awaiter(this, void 0, void 0, function* () { - console.log("saved", editor.getPath()); - onDisk = true; - if (filePath !== event.path) { - console.log("file path changed to", event.path); - client = yield exports.clientResolver.get(event.path); - } - filePath = event.path; - }); - }); - var destroyObserver = editor.onDidDestroy(() => { - client.executeClose({ file: editor.getPath() }); - changeObserver.dispose(); - fasterChangeObserver.dispose(); - saveObserver.dispose(); - destroyObserver.dispose(); - }); - } - 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(); + } + })); }); } exports.activate = activate; -function updatePanelConfig(filePath) { - exports.clientResolver.get(filePath).then(client => { - client.executeProjectInfo({ - needFileNameList: false, - file: filePath - }).then(result => { - mainPanelView.panelView.setTsconfigInUse(result.body.configFileName); - }, err => { - mainPanelView.panelView.setTsconfigInUse(''); - }); - }); -} function deactivate() { - if (statusBarMessage) - statusBarMessage.destroy(); - if (editorWatch) - editorWatch.dispose(); - if (autoCompleteWatch) - autoCompleteWatch.dispose(); + subscriptions.dispose(); } exports.deactivate = deactivate; function serialize() { diff --git a/dist/main/error_pusher.js b/dist/main/error_pusher.js index d71785df3..584d22769 100644 --- a/dist/main/error_pusher.js +++ b/dist/main/error_pusher.js @@ -2,7 +2,7 @@ const lodash_1 = require("lodash"); const tsUtil_1 = require("./utils/tsUtil"); class ErrorPusher { - constructor(linter) { + constructor() { this.errors = new Map(); this.pushErrors = lodash_1.debounce(() => { const errors = []; @@ -18,9 +18,10 @@ class ErrorPusher { } } } - this.linter.setMessages(errors); + if (this.linter) { + this.linter.setMessages(errors); + } }, 100); - this.linter = linter; } addErrors(prefix, filePath, errors) { let prefixed = this.errors.get(prefix); @@ -32,7 +33,13 @@ class ErrorPusher { this.pushErrors(); } clear() { - console.log("clearing errors"); + if (this.linter) { + this.linter.deleteMessages(); + } + } + setLinter(linter) { + this.linter = linter; + this.pushErrors(); } } exports.ErrorPusher = ErrorPusher; diff --git a/dist/main/typescript_editor_pane.js b/dist/main/typescript_editor_pane.js new file mode 100644 index 000000000..58d956632 --- /dev/null +++ b/dist/main/typescript_editor_pane.js @@ -0,0 +1,133 @@ +"use strict"; +const tslib_1 = require("tslib"); +const atom_space_pen_views_1 = require("atom-space-pen-views"); +const atom_1 = require("atom"); +const atomts_1 = require("./atomts"); +const tsUtil_1 = require("./utils/tsUtil"); +const path_1 = require("path"); +const tooltipManager = require("./atom/tooltipManager"); +const mainPanelView = require("./atom/views/mainPanelView"); +class TypescriptEditorPane { + constructor(editor, opts) { + this.isTypescript = false; + this.isTSConfig = false; + this.isOpen = false; + this.occurrenceMarkers = []; + this.subscriptions = new atom_1.CompositeDisposable(); + this.onActivated = () => { + this.activeAt = Date.now(); + if (this.isTypescript && this.filePath) { + mainPanelView.show(); + } + }; + this.onDeactivated = () => { + mainPanelView.hide(); + }; + this.onDidChange = diff => { + if (this.isOpen) { + this.client.executeChange({ + endLine: diff.oldRange.end.row + 1, + endOffset: diff.oldRange.end.column + 1, + file: this.editor.getPath(), + line: diff.oldRange.start.row + 1, + offset: diff.oldRange.start.column + 1, + insertString: diff.newText, + }); + } + }; + this.onDidChangeCursorPosition = () => { + if (!this.isTypescript) { + return; + } + for (const marker of this.occurrenceMarkers) { + marker.destroy(); + } + const pos = this.editor.getLastCursor().getBufferPosition(); + this.client.executeOccurances({ + file: this.filePath, + line: pos.row + 1, + offset: pos.column + 1 + }).then(result => { + for (const ref of result.body) { + const marker = this.editor.markBufferRange(tsUtil_1.spanToRange(ref)); + this.editor.decorateMarker(marker, { + type: "highlight", + class: "atom-typescript-occurrence" + }); + this.occurrenceMarkers.push(marker); + } + }).catch(() => null); + }; + this.onDidSave = (event) => tslib_1.__awaiter(this, void 0, void 0, function* () { + console.log("saved", this.editor.getPath()); + if (this.filePath !== event.path) { + console.log("file path changed to", event.path); + this.client = yield atomts_1.clientResolver.get(event.path); + this.filePath = event.path; + } + }); + this.onDidStopChanging = () => { + if ((this.isTypescript && this.filePath) || this.isTSConfig) { + this.checkErrors(this); + } + }; + this.checkErrors = opts.checkErrors; + this.editor = editor; + this.filePath = editor.getPath(); + this.isTypescript = isTypescriptGrammar(editor.getGrammar()); + this.subscriptions.add(editor.onDidChangeGrammar(grammar => { + this.isTypescript = isTypescriptGrammar(grammar); + })); + if (this.filePath) { + this.isTSConfig = path_1.basename(this.filePath) === "tsconfig.json"; + } + console.log("opened", this.filePath); + atomts_1.clientResolver.get(this.filePath).then(client => { + this.client = client; + this.subscriptions.add(editor.buffer.onDidChange(this.onDidChange)); + this.subscriptions.add(editor.onDidChangeCursorPosition(this.onDidChangeCursorPosition)); + this.subscriptions.add(editor.onDidSave(this.onDidSave)); + this.subscriptions.add(editor.onDidStopChanging(this.onDidStopChanging)); + if (this.isTypescript && this.filePath) { + this.client.executeOpen({ + file: this.filePath, + fileContent: this.editor.getText() + }); + this.checkErrors(this); + this.isOpen = true; + this.updatePanelConfig(); + } + }); + this.setupTooltipView(); + } + dispose() { + return tslib_1.__awaiter(this, void 0, void 0, function* () { + this.subscriptions.dispose(); + if (this.isOpen) { + this.client.executeClose({ file: this.filePath }); + } + }); + } + setupTooltipView() { + const editorView = atom_space_pen_views_1.$(atom.views.getView(this.editor)); + tooltipManager.attach(editorView, this.editor); + } + updatePanelConfig() { + return tslib_1.__awaiter(this, void 0, void 0, function* () { + let configPath = ""; + try { + const result = yield this.client.executeProjectInfo({ + needFileNameList: false, + file: this.filePath + }); + configPath = result.body.configFileName; + } + catch (error) { } + mainPanelView.panelView.setTsconfigInUse(configPath); + }); + } +} +exports.TypescriptEditorPane = TypescriptEditorPane; +function isTypescriptGrammar(grammar) { + return grammar.scopeName === "source.ts" || grammar.scopeName === "source.tsx"; +} diff --git a/lib/client/clientResolver.ts b/lib/client/clientResolver.ts index 80ca9319d..d14037a75 100644 --- a/lib/client/clientResolver.ts +++ b/lib/client/clientResolver.ts @@ -2,7 +2,7 @@ import {TypescriptServiceClient as Client} from "./client" import * as events from "events" import * as path from "path" import * as nodeResolve from "resolve" -import {Diagnostic, DiagnosticEventBody} from "typescript/lib/protocol" +import {Diagnostic, DiagnosticEventBody, ConfigFileDiagnosticEventBody} from "typescript/lib/protocol" type DiagnosticTypes = "configFileDiag" | "semanticDiag" | "syntaxDiag" @@ -55,11 +55,11 @@ export class ClientResolver extends events.EventEmitter { this.emit("pendingRequestsChange") }) - const diagnosticHandler = (type: string, result: DiagnosticEventBody) => { + const diagnosticHandler = (type: string, result: DiagnosticEventBody | ConfigFileDiagnosticEventBody) => { this.emit("diagnostics", { type, serverPath, - filePath: result.file, + filePath: isConfDiagBody(result) ? result.configFile : result.file, diagnostics: result.diagnostics }) } @@ -86,3 +86,7 @@ export function resolveServer(sourcePath: string): Promise { }) }) } + +function isConfDiagBody(body: any): body is ConfigFileDiagnosticEventBody { + return body && body.triggerFile && body.configFile +} diff --git a/lib/main/atom/atomUtils.ts b/lib/main/atom/atomUtils.ts index ece3f3dd7..812512663 100644 --- a/lib/main/atom/atomUtils.ts +++ b/lib/main/atom/atomUtils.ts @@ -293,4 +293,4 @@ export function openFile(filePath: string, position: { line?: number; col?: numb config.initialColumn = position.col; } atom.workspace.open(filePath, config); -} \ No newline at end of file +} diff --git a/lib/main/atomts.ts b/lib/main/atomts.ts index d5b3e7e3e..76705e513 100644 --- a/lib/main/atomts.ts +++ b/lib/main/atomts.ts @@ -3,34 +3,32 @@ console.profile("atomts init") const startTime = process.hrtime() -import {$} from "atom-space-pen-views" -import {debounce} from "lodash" +// import {getFileStatus} from "./atom/fileStatusCache" +// import {$} from "atom-space-pen-views" import {ClientResolver} from "../client/clientResolver" -import {getFileStatus} from "./atom/fileStatusCache" +import {CompositeDisposable} from "atom" +import {debounce} from "lodash" +import {ErrorPusher} from "./error_pusher" +import {LinterRegistry, Linter} from "../typings/linter" +import {TypescriptEditorPane} from "./typescript_editor_pane" import * as atomConfig from './atom/atomConfig' -import * as atomUtils from './atom/atomUtils' +// import * as atomUtils from './atom/atomUtils' import * as autoCompleteProvider from './atom/autoCompleteProvider' import * as commands from "./atom/commands/commands" -import * as fs from 'fs' +// import * as fs from 'fs' import * as hyperclickProvider from "../hyperclickProvider" import * as mainPanel from "../main/atom/views/mainPanelView" import * as mainPanelView from "./atom/views/mainPanelView" -import * as path from 'path' +// import * as path from 'path' import * as renameView from './atom/views/renameView' -import * as tooltipManager from './atom/tooltipManager' import * as tsconfig from "tsconfig/dist/tsconfig" -import {spanToRange} from "./utils/tsUtil" -import {LinterRegistry, Linter} from "../typings/linter" -import {ErrorPusher} from "./error_pusher" // globals export const clientResolver = new ClientResolver() export const config = atomConfig.schema let linter: Linter -let errorPusher: ErrorPusher -let statusBarMessage -let editorWatch: AtomCore.Disposable -let autoCompleteWatch: AtomCore.Disposable +const errorPusher = new ErrorPusher() +const subscriptions = new CompositeDisposable() interface PackageState {} @@ -44,252 +42,72 @@ clientResolver.on("pendingRequestsChange", () => { mainPanel.panelView.updatePendingRequests([].concat.apply([], pending)) }) -var hideIfNotActiveOnStart = debounce(() => { - // Only show if this editor is active: - var editor = atom.workspace.getActiveTextEditor(); - if (!atomUtils.onDiskAndTsRelated(editor)) { - mainPanelView.hide(); - } -}, 100); - export function activate(state: PackageState) { - console.log("activating them package", state) - require('atom-package-deps').install('atom-typescript').then(() => { - if (linter) { - errorPusher = new ErrorPusher(linter) + if (linter) { + errorPusher.setLinter(linter) - clientResolver.on("diagnostics", ({type, serverPath, filePath, diagnostics}) => { - errorPusher.addErrors(type + serverPath, filePath, diagnostics) - }) - } + clientResolver.on("diagnostics", ({type, serverPath, filePath, diagnostics}) => { + errorPusher.addErrors(type + serverPath, filePath, diagnostics) + }) + } - mainPanelView.attach(); + mainPanelView.attach() + mainPanelView.hide() - // Add the rename view - renameView.attach(); + // Add the rename view + renameView.attach() - // Observe changed active editor - atom.workspace.onDidChangeActivePaneItem((editor: AtomCore.IEditor) => { - console.log("did change active panel", editor) + // Register the commands + commands.registerCommands() - if (atomUtils.onDiskAndTs(editor)) { - var filePath = editor.getPath(); + const panes: TypescriptEditorPane[] = [] - updatePanelConfig(filePath); + const checkErrors = debounce((pane: TypescriptEditorPane) => { + console.log("checking errors for all panes for", pane.filePath) - mainPanelView.panelView.updateFileStatus(filePath); - mainPanelView.show(); - } - else if (atomUtils.onDiskAndTsRelated(editor)){ - mainPanelView.show(); - } - else { - mainPanelView.hide(); - } - }); - - // Observe editors loading - editorWatch = atom.workspace.observeTextEditors(async function(editor: AtomCore.IEditor) { - let filePath = editor.getPath() - console.log("opened editor", filePath) - - let client = await clientResolver.get(filePath) - console.log("found client for editor", {filePath, client}) - - // subscribe for tooltips - // inspiration : https://github.com/chaika2013/ide-haskell - var editorView = $(atom.views.getView(editor)) - tooltipManager.attach(editorView, editor) - - var ext = path.extname(filePath); - if (atomUtils.isAllowedExtension(ext)) { - try { - client.executeOpen({ - file: filePath, - fileContent: editor.getText() - }) - - updatePanelConfig(filePath); - - // 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(); - - if (onDisk) { - - client.executeGetErr({files: [filePath], delay: 100}) - - // // 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); - // } - // }); - } - - const markers: AtomCore.IDisplayBufferMarker[] = [] - - editor.onDidChangeCursorPosition(() => { - for (const marker of markers) { - marker.destroy() - } - - const pos = editor.getLastCursor().getBufferPosition() - - client.executeOccurances({ - file: filePath, - line: pos.row+1, - offset: pos.column+1 - }).then(result => { - for (const ref of result.body) { - const marker = editor.markBufferRange(spanToRange(ref)) - editor.decorateMarker(marker as any, { - type: "highlight", - class: "atom-typescript-occurrence" - }) - markers.push(marker) - } - }).catch(() => null) - }) - - // 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) { - console.log("file is not on disk..") - return - } - - // Set errors in project per file - client.executeGetErr({files: [filePath], delay: 100}) - - // TODO: provide function completions - /*var position = atomUtils.getEditorPosition(editor); - signatureProvider.requestHandler({ - program: program, - editor: editor, - filePath: filePath, - position: position - });*/ - - }); - - 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(); - - client.executeChange({ - endLine: diff.oldRange.end.row+1, - endOffset: diff.oldRange.end.column+1, - file: editor.getPath(), - line: diff.oldRange.start.row+1, - offset: diff.oldRange.start.column+1, - insertString: diff.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(async function(event) { - console.log("saved", editor.getPath()) - - onDisk = true - // If this is a saveAs event.path will be different so we should change it - - if (filePath !== event.path) { - console.log("file path changed to", event.path) - client = await clientResolver.get(event.path) - } - - filePath = event.path - }); - - // Observe editors closing - var destroyObserver = editor.onDidDestroy(() => { - client.executeClose({file: editor.getPath()}) - - // Clear editor observers - changeObserver.dispose(); - fasterChangeObserver.dispose(); - saveObserver.dispose(); - destroyObserver.dispose(); - - }); - - } catch (ex) { - console.error('Solve this in atom-typescript', ex); - throw ex; - } - } - }); + const files = panes + .sort((a, b) => a.activeAt - b.activeAt) + .filter(_pane => _pane.filePath && _pane.isTypescript && _pane.client === pane.client) + .map(pane => pane.filePath) - // Register the commands - commands.registerCommands(); + pane.client.executeGetErr({files, delay: 100}) - }) -} + }, 50) + + subscriptions.add(atom.workspace.observeTextEditors((editor: AtomCore.IEditor) => { + panes.push(new TypescriptEditorPane(editor, { + checkErrors + })) + })) + + let activePane: TypescriptEditorPane = panes.find(pane => + pane.editor === atom.workspace.getActiveTextEditor()) -/** Update the panel with the configu resolved from the given source file */ -function updatePanelConfig(filePath: string) { - clientResolver.get(filePath).then(client => { - client.executeProjectInfo({ - needFileNameList: false, - file: filePath - }).then(result => { - mainPanelView.panelView.setTsconfigInUse(result.body.configFileName) - }, err => { - mainPanelView.panelView.setTsconfigInUse(''); + if (activePane) { + activePane.onActivated() + } + + subscriptions.add(atom.workspace.onDidChangeActivePaneItem((editor: AtomCore.IEditor) => { + if (activePane) { + activePane.onDeactivated() + activePane = null + } + + 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(); + subscriptions.dispose() } export function serialize(): PackageState { diff --git a/lib/main/error_pusher.ts b/lib/main/error_pusher.ts index 97115d622..da4288e6b 100644 --- a/lib/main/error_pusher.ts +++ b/lib/main/error_pusher.ts @@ -5,14 +5,9 @@ import {locationsToRange} from "./utils/tsUtil" /** Class that collects errors from all of the clients and pushes them to the Linter service */ export class ErrorPusher { - linter: Linter - + private linter?: Linter private errors: Map> = new Map() - constructor(linter: Linter) { - this.linter = linter - } - /** Add errors. Previous errors with the same prefix and filePath are going to be replaced */ addErrors(prefix: string, filePath: string, errors: Diagnostic[]) { let prefixed = this.errors.get(prefix) @@ -28,7 +23,14 @@ export class ErrorPusher { /** Clear all errors */ clear() { - console.log("clearing errors") + if (this.linter) { + this.linter.deleteMessages() + } + } + + setLinter(linter: Linter) { + this.linter = linter + this.pushErrors() } private pushErrors = debounce(() => { @@ -47,11 +49,9 @@ export class ErrorPusher { } } - this.linter.setMessages(errors) + if (this.linter) { + this.linter.setMessages(errors) + } }, 100) } - -// function rangeFromTS(start: protocol.): atom.Range { -// -// } diff --git a/lib/main/typescript_editor_pane.ts b/lib/main/typescript_editor_pane.ts new file mode 100644 index 000000000..9e3c4ff50 --- /dev/null +++ b/lib/main/typescript_editor_pane.ts @@ -0,0 +1,178 @@ +import {$} from "atom-space-pen-views" +import {CompositeDisposable} from "atom" +import {clientResolver} from "./atomts" +import {spanToRange} from "./utils/tsUtil" +import {TypescriptServiceClient} from "../client/client" +import {basename} from "path" +import * as tooltipManager from './atom/tooltipManager' +import * as mainPanelView from "./atom/views/mainPanelView" + +type onChangeObserver = (diff: { + oldRange: TextBuffer.IRange + newRange: TextBuffer.IRange + oldText: string + newText: string +}) => any + +interface PaneOptions { + checkErrors: (pane: TypescriptEditorPane) => any +} + +export class TypescriptEditorPane implements AtomCore.Disposable { + activeAt: number + + checkErrors: (pane: TypescriptEditorPane) => any + client: TypescriptServiceClient + filePath: string + + isTypescript = false + isTSConfig = false + + private isOpen = false + + readonly occurrenceMarkers: AtomCore.IDisplayBufferMarker[] = [] + readonly editor: AtomCore.IEditor + readonly subscriptions = new CompositeDisposable() + + constructor(editor: AtomCore.IEditor, opts: PaneOptions) { + this.checkErrors = opts.checkErrors + this.editor = editor + this.filePath = editor.getPath() + + this.isTypescript = isTypescriptGrammar(editor.getGrammar()) + + this.subscriptions.add(editor.onDidChangeGrammar(grammar => { + this.isTypescript = isTypescriptGrammar(grammar) + })) + + if (this.filePath) { + this.isTSConfig = basename(this.filePath) === "tsconfig.json" + } + + console.log("opened", this.filePath) + + clientResolver.get(this.filePath).then(client => { + this.client = client + + this.subscriptions.add(editor.buffer.onDidChange(this.onDidChange)) + this.subscriptions.add(editor.onDidChangeCursorPosition(this.onDidChangeCursorPosition)) + this.subscriptions.add(editor.onDidSave(this.onDidSave)) + this.subscriptions.add(editor.onDidStopChanging(this.onDidStopChanging)) + + if (this.isTypescript && this.filePath) { + this.client.executeOpen({ + file: this.filePath, + fileContent: this.editor.getText() + }) + + this.checkErrors(this) + + this.isOpen = true + this.updatePanelConfig() + } + }) + + this.setupTooltipView() + } + + async dispose() { + this.subscriptions.dispose() + + if (this.isOpen) { + this.client.executeClose({file: this.filePath}) + } + } + + onActivated = () => { + this.activeAt = Date.now() + + if (this.isTypescript && this.filePath) { + mainPanelView.show() + } + } + + onDeactivated = () => { + mainPanelView.hide() + } + + onDidChange: onChangeObserver = diff => { + if (this.isOpen) { + this.client.executeChange({ + endLine: diff.oldRange.end.row+1, + endOffset: diff.oldRange.end.column+1, + file: this.editor.getPath(), + line: diff.oldRange.start.row+1, + offset: diff.oldRange.start.column+1, + insertString: diff.newText, + }) + } + } + + onDidChangeCursorPosition = () => { + if (!this.isTypescript) { + return + } + + for (const marker of this.occurrenceMarkers) { + marker.destroy() + } + + const pos = this.editor.getLastCursor().getBufferPosition() + + this.client.executeOccurances({ + file: this.filePath, + line: pos.row+1, + offset: pos.column+1 + }).then(result => { + 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(() => null) + } + + onDidSave = async event => { + // Observe editors saving + console.log("saved", this.editor.getPath()) + + if (this.filePath !== event.path) { + console.log("file path changed to", event.path) + this.client = await clientResolver.get(event.path) + this.filePath = event.path + } + } + + onDidStopChanging = () => { + if ((this.isTypescript && this.filePath) || this.isTSConfig) { + this.checkErrors(this) + } + } + + setupTooltipView() { + // subscribe for tooltips + // inspiration : https://github.com/chaika2013/ide-haskell + const editorView = $(atom.views.getView(this.editor)) + tooltipManager.attach(editorView, this.editor) + } + + async updatePanelConfig() { + let configPath = "" + try { + const result = await this.client.executeProjectInfo({ + needFileNameList: false, + file: this.filePath + }) + configPath = result.body.configFileName + } catch (error) {} + + mainPanelView.panelView.setTsconfigInUse(configPath) + } +} + +function isTypescriptGrammar(grammar: AtomCore.IGrammar): boolean { + return grammar.scopeName === "source.ts" || grammar.scopeName === "source.tsx" +} diff --git a/lib/typings/atom.d.ts b/lib/typings/atom.d.ts new file mode 100644 index 000000000..c6c2b0edb --- /dev/null +++ b/lib/typings/atom.d.ts @@ -0,0 +1,8 @@ +export {} + +declare module "atom" { + export class CompositeDisposable { + add(disposable: AtomCore.Disposable) + dispose() + } +} diff --git a/lib/typings/atom_core.d.ts b/lib/typings/atom_core.d.ts new file mode 100644 index 000000000..526c21c66 --- /dev/null +++ b/lib/typings/atom_core.d.ts @@ -0,0 +1,11 @@ +declare namespace AtomCore { + interface IEditor { + onDidChangeGrammar(callback: (grammar: IGrammar) => any): Disposable + } +} + +declare namespace TextBuffer { + interface ITextBuffer { + onDidChange(callback: Function): AtomCore.Disposable + } +} From 081cd0f17a778a17a60cd215ea47cb4afff4832b Mon Sep 17 00:00:00 2001 From: Guntars Asmanis-Graham Date: Sun, 4 Dec 2016 18:57:44 -0500 Subject: [PATCH 20/70] Only check all open files on save --- dist/client/client.js | 6 +++++- dist/main/atomts.js | 4 ++-- dist/main/typescript_editor_pane.js | 24 ++++++++++++++++++---- lib/client/client.ts | 6 +++++- lib/main/atomts.ts | 4 ++-- lib/main/typescript_editor_pane.ts | 31 +++++++++++++++++++++++------ 6 files changed, 59 insertions(+), 16 deletions(-) diff --git a/dist/client/client.js b/dist/client/client.js index 60b5c8b8f..0ce521f7a 100644 --- a/dist/client/client.js +++ b/dist/client/client.js @@ -57,6 +57,9 @@ class TypescriptServiceClient { executeQuickInfo(args) { return this.execute("quickinfo", args); } + executeReload(args) { + return this.execute("reload", args); + } execute(command, args) { return this.serverPromise.then(cp => { const expectResponse = !!TypescriptServiceClient.commandWithResponse[command]; @@ -139,7 +142,8 @@ TypescriptServiceClient.commandWithResponse = { completions: true, occurrences: true, projectInfo: true, - quickinfo: true + quickinfo: true, + reload: true, }; function isEvent(res) { return res.type === "event"; diff --git a/dist/main/atomts.js b/dist/main/atomts.js index 2803ee480..2f87e7cd8 100644 --- a/dist/main/atomts.js +++ b/dist/main/atomts.js @@ -40,7 +40,7 @@ function activate(state) { renameView.attach(); commands.registerCommands(); const panes = []; - const checkErrors = lodash_1.debounce((pane) => { + const onSave = lodash_1.debounce((pane) => { console.log("checking errors for all panes for", pane.filePath); const files = panes .sort((a, b) => a.activeAt - b.activeAt) @@ -50,7 +50,7 @@ function activate(state) { }, 50); subscriptions.add(atom.workspace.observeTextEditors((editor) => { panes.push(new typescript_editor_pane_1.TypescriptEditorPane(editor, { - checkErrors + onSave })); })); let activePane = panes.find(pane => pane.editor === atom.workspace.getActiveTextEditor()); diff --git a/dist/main/typescript_editor_pane.js b/dist/main/typescript_editor_pane.js index 58d956632..17d3135cf 100644 --- a/dist/main/typescript_editor_pane.js +++ b/dist/main/typescript_editor_pane.js @@ -18,6 +18,12 @@ class TypescriptEditorPane { this.activeAt = Date.now(); if (this.isTypescript && this.filePath) { mainPanelView.show(); + if (this.client) { + this.client.executeGetErr({ + files: [this.filePath], + delay: 100 + }); + } } }; this.onDeactivated = () => { @@ -64,14 +70,21 @@ class TypescriptEditorPane { console.log("file path changed to", event.path); this.client = yield atomts_1.clientResolver.get(event.path); this.filePath = event.path; + this.isTSConfig = path_1.basename(this.filePath) === "tsconfig.json"; + } + if (this.onSave) { + this.onSave(this); } }); this.onDidStopChanging = () => { - if ((this.isTypescript && this.filePath) || this.isTSConfig) { - this.checkErrors(this); + if (this.isTypescript && this.filePath) { + this.client.executeGetErr({ + files: [this.filePath], + delay: 100 + }); } }; - this.checkErrors = opts.checkErrors; + this.onSave = opts.onSave; this.editor = editor; this.filePath = editor.getPath(); this.isTypescript = isTypescriptGrammar(editor.getGrammar()); @@ -93,7 +106,10 @@ class TypescriptEditorPane { file: this.filePath, fileContent: this.editor.getText() }); - this.checkErrors(this); + this.client.executeGetErr({ + files: [this.filePath], + delay: 100 + }); this.isOpen = true; this.updatePanelConfig(); } diff --git a/lib/client/client.ts b/lib/client/client.ts index ea43db9ee..5deead65d 100644 --- a/lib/client/client.ts +++ b/lib/client/client.ts @@ -38,7 +38,8 @@ export class TypescriptServiceClient { completions: true, occurrences: true, projectInfo: true, - quickinfo: true + quickinfo: true, + reload: true, } executeChange(args: protocol.ChangeRequestArgs) { @@ -68,6 +69,9 @@ export class TypescriptServiceClient { executeQuickInfo(args: protocol.FileLocationRequestArgs): Promise { return this.execute("quickinfo", args) } + executeReload(args: protocol.ReloadRequestArgs): Promise { + return this.execute("reload", args) + } execute(command: string, args): Promise { return this.serverPromise.then(cp => { diff --git a/lib/main/atomts.ts b/lib/main/atomts.ts index 76705e513..7a7962141 100644 --- a/lib/main/atomts.ts +++ b/lib/main/atomts.ts @@ -64,7 +64,7 @@ export function activate(state: PackageState) { const panes: TypescriptEditorPane[] = [] - const checkErrors = debounce((pane: TypescriptEditorPane) => { + const onSave = debounce((pane: TypescriptEditorPane) => { console.log("checking errors for all panes for", pane.filePath) const files = panes @@ -78,7 +78,7 @@ export function activate(state: PackageState) { subscriptions.add(atom.workspace.observeTextEditors((editor: AtomCore.IEditor) => { panes.push(new TypescriptEditorPane(editor, { - checkErrors + onSave })) })) diff --git a/lib/main/typescript_editor_pane.ts b/lib/main/typescript_editor_pane.ts index 9e3c4ff50..c543ad0c5 100644 --- a/lib/main/typescript_editor_pane.ts +++ b/lib/main/typescript_editor_pane.ts @@ -15,13 +15,13 @@ type onChangeObserver = (diff: { }) => any interface PaneOptions { - checkErrors: (pane: TypescriptEditorPane) => any + onSave: (pane: TypescriptEditorPane) => any } export class TypescriptEditorPane implements AtomCore.Disposable { activeAt: number - checkErrors: (pane: TypescriptEditorPane) => any + onSave: (pane: TypescriptEditorPane) => any client: TypescriptServiceClient filePath: string @@ -35,7 +35,7 @@ export class TypescriptEditorPane implements AtomCore.Disposable { readonly subscriptions = new CompositeDisposable() constructor(editor: AtomCore.IEditor, opts: PaneOptions) { - this.checkErrors = opts.checkErrors + this.onSave = opts.onSave this.editor = editor this.filePath = editor.getPath() @@ -65,7 +65,10 @@ export class TypescriptEditorPane implements AtomCore.Disposable { fileContent: this.editor.getText() }) - this.checkErrors(this) + this.client.executeGetErr({ + files: [this.filePath], + delay: 100 + }) this.isOpen = true this.updatePanelConfig() @@ -88,6 +91,14 @@ export class TypescriptEditorPane implements AtomCore.Disposable { if (this.isTypescript && this.filePath) { mainPanelView.show() + + if (this.client) { + // The first activation might happen before we even have a client + this.client.executeGetErr({ + files: [this.filePath], + delay: 100 + }) + } } } @@ -143,12 +154,20 @@ export class TypescriptEditorPane implements AtomCore.Disposable { console.log("file path changed to", event.path) this.client = await clientResolver.get(event.path) this.filePath = event.path + this.isTSConfig = basename(this.filePath) === "tsconfig.json" + } + + if (this.onSave) { + this.onSave(this) } } onDidStopChanging = () => { - if ((this.isTypescript && this.filePath) || this.isTSConfig) { - this.checkErrors(this) + if (this.isTypescript && this.filePath) { + this.client.executeGetErr({ + files: [this.filePath], + delay: 100 + }) } } From c33ed0cd1561ecf362c9b37d4967c7ea57ff5c86 Mon Sep 17 00:00:00 2001 From: Guntars Asmanis-Graham Date: Sun, 4 Dec 2016 19:25:51 -0500 Subject: [PATCH 21/70] Make mainPanel not global --- dist/client/client.js | 3 +- dist/client/clientResolver.js | 1 - dist/main/atom/commands/commands.js | 13 +-- dist/main/atom/views/contextView.js | 4 +- dist/main/atom/views/mainPanelView.js | 93 +++----------------- dist/main/atomts.js | 24 +++--- dist/main/typescript_editor_pane.js | 12 +-- lib/main/atom/commands/commands.ts | 15 +--- lib/main/atom/views/contextView.ts | 70 --------------- lib/main/atom/views/mainPanelView.ts | 118 ++++---------------------- lib/main/atomts.ts | 30 +++---- lib/main/typescript_editor_pane.ts | 16 ++-- 12 files changed, 76 insertions(+), 323 deletions(-) delete mode 100644 lib/main/atom/views/contextView.ts diff --git a/dist/client/client.js b/dist/client/client.js index 0ce521f7a..c16251b70 100644 --- a/dist/client/client.js +++ b/dist/client/client.js @@ -1,5 +1,4 @@ "use strict"; -const tslib_1 = require("tslib"); const child_process_1 = require("child_process"); const stream_1 = require("stream"); const byline = require("byline"); @@ -137,7 +136,6 @@ class TypescriptServiceClient { } } } -exports.TypescriptServiceClient = TypescriptServiceClient; TypescriptServiceClient.commandWithResponse = { completions: true, occurrences: true, @@ -145,6 +143,7 @@ TypescriptServiceClient.commandWithResponse = { quickinfo: true, reload: true, }; +exports.TypescriptServiceClient = TypescriptServiceClient; function isEvent(res) { return res.type === "event"; } diff --git a/dist/client/clientResolver.js b/dist/client/clientResolver.js index 965197519..107ad4f24 100644 --- a/dist/client/clientResolver.js +++ b/dist/client/clientResolver.js @@ -1,5 +1,4 @@ "use strict"; -const tslib_1 = require("tslib"); const client_1 = require("./client"); const events = require("events"); const path = require("path"); diff --git a/dist/main/atom/commands/commands.js b/dist/main/atom/commands/commands.js index d79cbbe23..6fb883269 100644 --- a/dist/main/atom/commands/commands.js +++ b/dist/main/atom/commands/commands.js @@ -3,20 +3,11 @@ function __export(m) { for (var p in m) if (!exports.hasOwnProperty(p)) exports[p] = m[p]; } const atomts_1 = require("../../atomts"); -const atomUtils = require("../atomUtils"); const autoCompleteProvider = require("../autoCompleteProvider"); -const contextView = require("../views/contextView"); const typeOverlayView_1 = require("../views/typeOverlayView"); const gotoHistory = require("../gotoHistory"); -const mainPanelView_1 = require("../views/mainPanelView"); __export(require("../components/componentRegistry")); function registerCommands() { - var theContextView; - 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(); }); @@ -60,9 +51,7 @@ function registerCommands() { gotoHistory.gotoPrevious(); }); atom.commands.add('atom-workspace', 'typescript:sync', (e) => { - if (!atomUtils.commandForTypeScript(e)) - return; - mainPanelView_1.panelView.softReset(); + console.log("typescript:sync trigerred"); }); } exports.registerCommands = registerCommands; diff --git a/dist/main/atom/views/contextView.js b/dist/main/atom/views/contextView.js index b7a2dff15..138e341bf 100644 --- a/dist/main/atom/views/contextView.js +++ b/dist/main/atom/views/contextView.js @@ -1,4 +1,5 @@ "use strict"; +const tslib_1 = require("tslib"); const sp = require("atom-space-pen-views"); const mainPanelView = require("./mainPanelView"); var titles = { @@ -24,9 +25,6 @@ class ContextView extends sp.SelectListView { if (item.title == titles.togglePanel) { mainPanelView.panelView.toggle(); } - if (item.title == titles.tabErrors) { - mainPanelView.panelView.errorPanelSelected(); - } if (item.title == titles.tabLastBuild) { mainPanelView.panelView.buildPanelSelected(); } diff --git a/dist/main/atom/views/mainPanelView.js b/dist/main/atom/views/mainPanelView.js index df518d011..0ca3667f2 100644 --- a/dist/main/atom/views/mainPanelView.js +++ b/dist/main/atom/views/mainPanelView.js @@ -3,8 +3,7 @@ const tslib_1 = require("tslib"); const view = require("./view"); const lineMessageView = require("./lineMessageView"); const atomUtils = require("../atomUtils"); -var panelHeaders = { - error: 'Errors In Open Files', +const panelHeaders = { build: 'Last Build Output', references: 'References' }; @@ -14,7 +13,6 @@ class MainPanelView extends view.View { super(...arguments); this.pendingRequests = []; this.expanded = false; - this.clearedError = true; } static content() { var btn = (view, text, className = '') => this.button({ @@ -46,8 +44,7 @@ class MainPanelView extends view.View { class: 'btn-group', style: 'margin-left: 6px; flex: 1 0 auto' }, () => { - btn('error', panelHeaders.error, 'selected'); - btn('build', panelHeaders.build); + btn('build', panelHeaders.build, 'selected'); btn('references', panelHeaders.references); }); }); @@ -113,11 +110,6 @@ class MainPanelView extends view.View { }); }); }); - 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', @@ -175,13 +167,6 @@ class MainPanelView extends view.View { this.sectionPending.animate({ opacity: 0 }, 200); } } - errorPanelSelectedClick() { - this.toggleIfThisIsntSelected(this.errorPanelBtn); - this.errorPanelSelected(); - } - errorPanelSelected() { - this.selectPanel(this.errorPanelBtn, this.errorBody, gotoHistory.errorsInOpenFiles); - } buildPanelSelectedClick() { this.toggleIfThisIsntSelected(this.buildPanelBtn); this.buildPanelSelected(); @@ -202,8 +187,8 @@ class MainPanelView extends view.View { } } selectPanel(btn, body, activeList) { - var buttons = [this.errorPanelBtn, this.buildPanelBtn, this.referencesPanelBtn]; - var bodies = [this.errorBody, this.buildBody, this.referencesBody]; + var buttons = [this.buildPanelBtn, this.referencesPanelBtn]; + var bodies = [this.buildBody, this.referencesBody]; buttons.forEach(b => { if (b !== btn) b.removeClass('selected'); @@ -226,9 +211,6 @@ class MainPanelView extends view.View { gotoHistory.activeList.lastPosition = null; } setActivePanel() { - if (this.errorPanelBtn.hasClass('selected')) { - this.errorPanelSelected(); - } if (this.buildPanelBtn.hasClass('selected')) { this.buildPanelSelected(); } @@ -266,48 +248,6 @@ class MainPanelView extends view.View { gotoHistory.referencesOutput.members.push({ filePath: ref.filePath, line: ref.position.line + 1, col: ref.position.col }); } } - clearError() { - this.clearedError = true; - this.clearSummary(); - this.errorBody.empty(); - } - addError(view) { - if (this.clearedError && view.getSummary) { - this.setErrorSummary(view.getSummary()); - } - this.clearedError = false; - this.errorBody.append(view.$); - } - setErrorSummary(summary) { - var message = summary.summary, className = summary.className, handler = summary.handler || undefined; - this.summary.html(message); - if (className) { - this.summary.addClass(className); - } - if (handler) { - handler(this.summary); - } - } - clearSummary() { - this.summary.html(''); - this.summary.off(); - } - setErrorPanelErrorCount(fileErrorCount, totalErrorCount) { - 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); - } setBuildPanelCount(errorCount, inProgressBuild = false) { var titleMain = inProgressBuild ? "Build Progress" : panelHeaders.build; var title = `${titleMain} ( No Errors )`; @@ -363,24 +303,13 @@ class MainPanelView extends 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); + const view = new MainPanelView({}); + atom.workspace.addBottomPanel({ item: view, priority: 1000, visible: true }); + return { + show() { view.$.show(); }, + hide() { view.$.hide(); }, + view + }; } 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; diff --git a/dist/main/atomts.js b/dist/main/atomts.js index 2f87e7cd8..b037ccdd8 100644 --- a/dist/main/atomts.js +++ b/dist/main/atomts.js @@ -11,32 +11,29 @@ const atomConfig = require("./atom/atomConfig"); const autoCompleteProvider = require("./atom/autoCompleteProvider"); const commands = require("./atom/commands/commands"); const hyperclickProvider = require("../hyperclickProvider"); -const mainPanel = require("../main/atom/views/mainPanelView"); -const mainPanelView = require("./atom/views/mainPanelView"); +const mainPanelView_1 = require("./atom/views/mainPanelView"); const renameView = require("./atom/views/renameView"); const tsconfig = require("tsconfig/dist/tsconfig"); +const subscriptions = new atom_1.CompositeDisposable(); exports.clientResolver = new clientResolver_1.ClientResolver(); exports.config = atomConfig.schema; let linter; -const errorPusher = new error_pusher_1.ErrorPusher(); -const subscriptions = new atom_1.CompositeDisposable(); -exports.clientResolver.on("pendingRequestsChange", () => { - if (!mainPanel.panelView) - return; - const pending = Object.keys(exports.clientResolver.clients) - .map(serverPath => exports.clientResolver.clients[serverPath].pending); - mainPanel.panelView.updatePendingRequests([].concat.apply([], pending)); -}); function activate(state) { require('atom-package-deps').install('atom-typescript').then(() => { + const mainPanel = mainPanelView_1.attach(); + const errorPusher = new error_pusher_1.ErrorPusher(); + mainPanel.hide(); + exports.clientResolver.on("pendingRequestsChange", () => { + const pending = Object.keys(exports.clientResolver.clients) + .map(serverPath => exports.clientResolver.clients[serverPath].pending); + mainPanel.view.updatePendingRequests([].concat.apply([], pending)); + }); if (linter) { errorPusher.setLinter(linter); exports.clientResolver.on("diagnostics", ({ type, serverPath, filePath, diagnostics }) => { errorPusher.addErrors(type + serverPath, filePath, diagnostics); }); } - mainPanelView.attach(); - mainPanelView.hide(); renameView.attach(); commands.registerCommands(); const panes = []; @@ -50,6 +47,7 @@ function activate(state) { }, 50); subscriptions.add(atom.workspace.observeTextEditors((editor) => { panes.push(new typescript_editor_pane_1.TypescriptEditorPane(editor, { + mainPanel, onSave })); })); diff --git a/dist/main/typescript_editor_pane.js b/dist/main/typescript_editor_pane.js index 17d3135cf..ca0bc2c17 100644 --- a/dist/main/typescript_editor_pane.js +++ b/dist/main/typescript_editor_pane.js @@ -1,12 +1,11 @@ "use strict"; const tslib_1 = require("tslib"); const atom_space_pen_views_1 = require("atom-space-pen-views"); -const atom_1 = require("atom"); +const path_1 = require("path"); const atomts_1 = require("./atomts"); +const atom_1 = require("atom"); const tsUtil_1 = require("./utils/tsUtil"); -const path_1 = require("path"); const tooltipManager = require("./atom/tooltipManager"); -const mainPanelView = require("./atom/views/mainPanelView"); class TypescriptEditorPane { constructor(editor, opts) { this.isTypescript = false; @@ -17,7 +16,7 @@ class TypescriptEditorPane { this.onActivated = () => { this.activeAt = Date.now(); if (this.isTypescript && this.filePath) { - mainPanelView.show(); + this.mainPanel.show(); if (this.client) { this.client.executeGetErr({ files: [this.filePath], @@ -27,7 +26,7 @@ class TypescriptEditorPane { } }; this.onDeactivated = () => { - mainPanelView.hide(); + this.mainPanel.hide(); }; this.onDidChange = diff => { if (this.isOpen) { @@ -85,6 +84,7 @@ class TypescriptEditorPane { } }; this.onSave = opts.onSave; + this.mainPanel = opts.mainPanel; this.editor = editor; this.filePath = editor.getPath(); this.isTypescript = isTypescriptGrammar(editor.getGrammar()); @@ -139,7 +139,7 @@ class TypescriptEditorPane { configPath = result.body.configFileName; } catch (error) { } - mainPanelView.panelView.setTsconfigInUse(configPath); + this.mainPanel.view.setTsconfigInUse(configPath); }); } } diff --git a/lib/main/atom/commands/commands.ts b/lib/main/atom/commands/commands.ts index 22f860f3a..0ceb8d8b7 100644 --- a/lib/main/atom/commands/commands.ts +++ b/lib/main/atom/commands/commands.ts @@ -1,15 +1,13 @@ import {clientResolver} from "../../atomts" -import atomUtils = require("../atomUtils"); +// import atomUtils = require("../atomUtils"); import autoCompleteProvider = require("../autoCompleteProvider"); // import path = require('path'); // 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 {simpleSelectionView} from "../views/simpleSelectionView"; // import escapeHtml = require('escape-html'); @@ -99,12 +97,6 @@ export function registerCommands() { // }); // }); - 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(); }); @@ -271,9 +263,10 @@ export function registerCommands() { // }, 400); atom.commands.add('atom-workspace', 'typescript:sync', (e) => { - if (!atomUtils.commandForTypeScript(e)) return; + console.log("typescript:sync trigerred") - panelView.softReset(); + // if (!atomUtils.commandForTypeScript(e)) return; + // panelView.softReset(); }); } diff --git a/lib/main/atom/views/contextView.ts b/lib/main/atom/views/contextView.ts deleted file mode 100644 index 10f9d4677..000000000 --- a/lib/main/atom/views/contextView.ts +++ /dev/null @@ -1,70 +0,0 @@ -import sp = require('atom-space-pen-views'); -import mainPanelView = require('./mainPanelView'); - -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', -} - -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(); - } - - 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/mainPanelView.ts b/lib/main/atom/views/mainPanelView.ts index 3471020a9..dc7ec0620 100644 --- a/lib/main/atom/views/mainPanelView.ts +++ b/lib/main/atom/views/mainPanelView.ts @@ -3,8 +3,7 @@ import view = require('./view'); import lineMessageView = require('./lineMessageView'); import atomUtils = require("../atomUtils"); -var panelHeaders = { - error: 'Errors In Open Files', +const panelHeaders = { build: 'Last Build Output', references: 'References' } @@ -14,12 +13,9 @@ import gotoHistory = require('../gotoHistory'); export class MainPanelView extends view.View { private tsconfigInUse: JQuery; - private summary: JQuery; - private errorPanelBtn: JQuery; private buildPanelBtn: JQuery; private referencesPanelBtn: JQuery; - private errorBody: JQuery; private buildBody: JQuery; private referencesBody: JQuery; @@ -62,8 +58,7 @@ export class MainPanelView extends view.View { class: 'btn-group', style: 'margin-left: 6px; flex: 1 0 auto' }, () => { - btn('error', panelHeaders.error, 'selected') - btn('build', panelHeaders.build) + btn('build', panelHeaders.build, 'selected') btn('references', panelHeaders.references) }); }); @@ -138,11 +133,6 @@ export class MainPanelView extends view.View { }); }); - 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', @@ -241,15 +231,6 @@ export class MainPanelView extends view.View { } } - ///// 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(); @@ -273,8 +254,8 @@ export class MainPanelView extends view.View { } private selectPanel(btn: JQuery, body: JQuery, activeList: TabWithGotoPositions) { - var buttons = [this.errorPanelBtn, this.buildPanelBtn, this.referencesPanelBtn]; - var bodies = [this.errorBody, this.buildBody, this.referencesBody]; + var buttons = [this.buildPanelBtn, this.referencesPanelBtn]; + var bodies = [this.buildBody, this.referencesBody]; buttons.forEach(b=> { if (b !== btn) @@ -300,9 +281,6 @@ export class MainPanelView extends view.View { } private setActivePanel() { - if (this.errorPanelBtn.hasClass('selected')) { - this.errorPanelSelected(); - } if (this.buildPanelBtn.hasClass('selected')) { this.buildPanelSelected(); } @@ -354,64 +332,6 @@ export class MainPanelView extends view.View { } } - ///////////// 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, - 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; @@ -481,24 +401,20 @@ export class MainPanelView extends view.View { } } -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 interface MainPanel { + show() + hide() + view: MainPanelView } -export function show() { - if (!panelView) return; - panelView.$.show(); -} +export function attach(): MainPanel { + const view = new MainPanelView({}) + + atom.workspace.addBottomPanel({ item: view, priority: 1000, visible: true }) -export function hide() { - if (!panelView) return; - panelView.$.hide(); + return { + show() { view.$.show() }, + hide() { view.$.hide() }, + view + } } diff --git a/lib/main/atomts.ts b/lib/main/atomts.ts index 7a7962141..d31c03a75 100644 --- a/lib/main/atomts.ts +++ b/lib/main/atomts.ts @@ -17,33 +17,33 @@ import * as autoCompleteProvider from './atom/autoCompleteProvider' import * as commands from "./atom/commands/commands" // import * as fs from 'fs' import * as hyperclickProvider from "../hyperclickProvider" -import * as mainPanel from "../main/atom/views/mainPanelView" -import * as mainPanelView from "./atom/views/mainPanelView" +import {attach as attachMainPanel} from "./atom/views/mainPanelView" // import * as path from 'path' import * as renameView from './atom/views/renameView' import * as tsconfig from "tsconfig/dist/tsconfig" // globals +const subscriptions = new CompositeDisposable() export const clientResolver = new ClientResolver() export const config = atomConfig.schema let linter: Linter -const errorPusher = new ErrorPusher() -const subscriptions = new CompositeDisposable() interface PackageState {} -clientResolver.on("pendingRequestsChange", () => { - // We only start once the panel view is initialized - if (!mainPanel.panelView) return; +export function activate(state: PackageState) { + require('atom-package-deps').install('atom-typescript').then(() => { + + const mainPanel = attachMainPanel() + const errorPusher = new ErrorPusher() - const pending = Object.keys(clientResolver.clients) - .map(serverPath => clientResolver.clients[serverPath].pending) + mainPanel.hide() - mainPanel.panelView.updatePendingRequests([].concat.apply([], pending)) -}) + clientResolver.on("pendingRequestsChange", () => { + const pending = Object.keys(clientResolver.clients) + .map(serverPath => clientResolver.clients[serverPath].pending) -export function activate(state: PackageState) { - require('atom-package-deps').install('atom-typescript').then(() => { + mainPanel.view.updatePendingRequests([].concat.apply([], pending)) + }) if (linter) { errorPusher.setLinter(linter) @@ -53,9 +53,6 @@ export function activate(state: PackageState) { }) } - mainPanelView.attach() - mainPanelView.hide() - // Add the rename view renameView.attach() @@ -78,6 +75,7 @@ export function activate(state: PackageState) { subscriptions.add(atom.workspace.observeTextEditors((editor: AtomCore.IEditor) => { panes.push(new TypescriptEditorPane(editor, { + mainPanel, onSave })) })) diff --git a/lib/main/typescript_editor_pane.ts b/lib/main/typescript_editor_pane.ts index c543ad0c5..83af5a97d 100644 --- a/lib/main/typescript_editor_pane.ts +++ b/lib/main/typescript_editor_pane.ts @@ -1,11 +1,11 @@ import {$} from "atom-space-pen-views" -import {CompositeDisposable} from "atom" +import {basename} from "path" import {clientResolver} from "./atomts" +import {CompositeDisposable} from "atom" +import {MainPanel} from "./atom/views/mainPanelView" import {spanToRange} from "./utils/tsUtil" import {TypescriptServiceClient} from "../client/client" -import {basename} from "path" import * as tooltipManager from './atom/tooltipManager' -import * as mainPanelView from "./atom/views/mainPanelView" type onChangeObserver = (diff: { oldRange: TextBuffer.IRange @@ -15,6 +15,7 @@ type onChangeObserver = (diff: { }) => any interface PaneOptions { + mainPanel: MainPanel onSave: (pane: TypescriptEditorPane) => any } @@ -28,6 +29,8 @@ export class TypescriptEditorPane implements AtomCore.Disposable { isTypescript = false isTSConfig = false + mainPanel: MainPanel + private isOpen = false readonly occurrenceMarkers: AtomCore.IDisplayBufferMarker[] = [] @@ -36,6 +39,7 @@ export class TypescriptEditorPane implements AtomCore.Disposable { constructor(editor: AtomCore.IEditor, opts: PaneOptions) { this.onSave = opts.onSave + this.mainPanel = opts.mainPanel this.editor = editor this.filePath = editor.getPath() @@ -90,7 +94,7 @@ export class TypescriptEditorPane implements AtomCore.Disposable { this.activeAt = Date.now() if (this.isTypescript && this.filePath) { - mainPanelView.show() + this.mainPanel.show() if (this.client) { // The first activation might happen before we even have a client @@ -103,7 +107,7 @@ export class TypescriptEditorPane implements AtomCore.Disposable { } onDeactivated = () => { - mainPanelView.hide() + this.mainPanel.hide() } onDidChange: onChangeObserver = diff => { @@ -188,7 +192,7 @@ export class TypescriptEditorPane implements AtomCore.Disposable { configPath = result.body.configFileName } catch (error) {} - mainPanelView.panelView.setTsconfigInUse(configPath) + this.mainPanel.view.setTsconfigInUse(configPath) } } From a2dd02e8c020dc392fed08bdd68a25022f583e5a Mon Sep 17 00:00:00 2001 From: Guntars Asmanis-Graham Date: Mon, 5 Dec 2016 02:07:47 -0500 Subject: [PATCH 22/70] =?UTF-8?q?*=20Update=20the=20config=20file=20name?= =?UTF-8?q?=20in=20panel=20better=20*=20Remove=20pane=20from=20the=20list?= =?UTF-8?q?=20when=20it=E2=80=99s=20disposed=20*=20Add=20a=20basic=20compi?= =?UTF-8?q?leOnSave=20feature?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- dist/client/client.js | 11 ++++++- dist/main/atomts.js | 6 ++++ dist/main/typescript_editor_pane.js | 50 ++++++++++++++++------------- lib/client/client.ts | 8 +++++ lib/main/atomts.ts | 7 ++++ 5 files changed, 59 insertions(+), 23 deletions(-) diff --git a/dist/client/client.js b/dist/client/client.js index c16251b70..8bfda4252 100644 --- a/dist/client/client.js +++ b/dist/client/client.js @@ -1,4 +1,5 @@ "use strict"; +const tslib_1 = require("tslib"); const child_process_1 = require("child_process"); const stream_1 = require("stream"); const byline = require("byline"); @@ -35,6 +36,12 @@ class TypescriptServiceClient { executeClose(args) { 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); } @@ -136,14 +143,16 @@ class TypescriptServiceClient { } } } +exports.TypescriptServiceClient = TypescriptServiceClient; TypescriptServiceClient.commandWithResponse = { + compileOnSaveAffectedFileList: true, + compileOnSaveEmitFile: true, completions: true, occurrences: true, projectInfo: true, quickinfo: true, reload: true, }; -exports.TypescriptServiceClient = TypescriptServiceClient; function isEvent(res) { return res.type === "event"; } diff --git a/dist/main/atomts.js b/dist/main/atomts.js index b037ccdd8..fa9b893d9 100644 --- a/dist/main/atomts.js +++ b/dist/main/atomts.js @@ -48,6 +48,12 @@ function activate(state) { subscriptions.add(atom.workspace.observeTextEditors((editor) => { panes.push(new typescript_editor_pane_1.TypescriptEditorPane(editor, { mainPanel, + onDispose(pane) { + if (activePane === pane) { + activePane = null; + } + panes.splice(panes.indexOf(pane), 1); + }, onSave })); })); diff --git a/dist/main/typescript_editor_pane.js b/dist/main/typescript_editor_pane.js index ca0bc2c17..82c02f7b9 100644 --- a/dist/main/typescript_editor_pane.js +++ b/dist/main/typescript_editor_pane.js @@ -8,13 +8,16 @@ const tsUtil_1 = require("./utils/tsUtil"); const tooltipManager = require("./atom/tooltipManager"); class TypescriptEditorPane { constructor(editor, opts) { - this.isTypescript = false; + this.configFile = ""; + this.isActive = false; this.isTSConfig = 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.mainPanel.show(); if (this.client) { @@ -24,8 +27,10 @@ class TypescriptEditorPane { }); } } + this.mainPanel.view.setTsconfigInUse(this.configFile); }; this.onDeactivated = () => { + this.isActive = false; this.mainPanel.hide(); }; this.onDidChange = diff => { @@ -74,6 +79,14 @@ class TypescriptEditorPane { if (this.onSave) { this.onSave(this); } + const result = yield this.client.executeCompileOnSaveAffectedFileList({ + file: this.filePath + }); + for (const project of result.body) { + for (const file of project.fileNames) { + this.client.executeCompileOnSaveEmitFile({ file }); + } + } }); this.onDidStopChanging = () => { if (this.isTypescript && this.filePath) { @@ -111,37 +124,30 @@ class TypescriptEditorPane { delay: 100 }); this.isOpen = true; - this.updatePanelConfig(); + this.client.executeProjectInfo({ + needFileNameList: false, + file: this.filePath + }).then(result => { + this.configFile = result.body.configFileName; + if (this.isActive) { + this.mainPanel.view.setTsconfigInUse(this.configFile); + } + }, error => null); } }); this.setupTooltipView(); } dispose() { - return tslib_1.__awaiter(this, void 0, void 0, function* () { - this.subscriptions.dispose(); - if (this.isOpen) { - this.client.executeClose({ file: this.filePath }); - } - }); + this.subscriptions.dispose(); + if (this.isOpen) { + this.client.executeClose({ file: this.filePath }); + } + this.onDispose(this); } setupTooltipView() { const editorView = atom_space_pen_views_1.$(atom.views.getView(this.editor)); tooltipManager.attach(editorView, this.editor); } - updatePanelConfig() { - return tslib_1.__awaiter(this, void 0, void 0, function* () { - let configPath = ""; - try { - const result = yield this.client.executeProjectInfo({ - needFileNameList: false, - file: this.filePath - }); - configPath = result.body.configFileName; - } - catch (error) { } - this.mainPanel.view.setTsconfigInUse(configPath); - }); - } } exports.TypescriptEditorPane = TypescriptEditorPane; function isTypescriptGrammar(grammar) { diff --git a/lib/client/client.ts b/lib/client/client.ts index 5deead65d..453c05227 100644 --- a/lib/client/client.ts +++ b/lib/client/client.ts @@ -35,6 +35,8 @@ export class TypescriptServiceClient { } static commandWithResponse = { + compileOnSaveAffectedFileList: true, + compileOnSaveEmitFile: true, completions: true, occurrences: true, projectInfo: true, @@ -48,6 +50,12 @@ export class TypescriptServiceClient { executeClose(args: protocol.FileRequestArgs) { 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) } diff --git a/lib/main/atomts.ts b/lib/main/atomts.ts index d31c03a75..39810b8b9 100644 --- a/lib/main/atomts.ts +++ b/lib/main/atomts.ts @@ -76,6 +76,13 @@ export function activate(state: PackageState) { subscriptions.add(atom.workspace.observeTextEditors((editor: AtomCore.IEditor) => { panes.push(new TypescriptEditorPane(editor, { mainPanel, + onDispose(pane) { + if (activePane === pane) { + activePane = null + } + + panes.splice(panes.indexOf(pane), 1) + }, onSave })) })) From a76ede1237ee81e22fe0c7b695920d0b12ebb0fb Mon Sep 17 00:00:00 2001 From: Guntars Asmanis-Graham Date: Mon, 5 Dec 2016 02:15:58 -0500 Subject: [PATCH 23/70] Create an empty StatusPanel --- dist/client/client.js | 3 +- dist/main/atom/components/statusBar.js | 16 ++++++ dist/main/atom/components/statusPanel.js | 28 ++++++++++ dist/main/atomts.js | 26 +++++---- dist/main/typescript_editor_pane.js | 8 +-- dist/main/utils/dom.js | 58 ++++++++++++++++++++ lib/main/atom/components/statusPanel.tsx | 39 ++++++++++++++ lib/main/atomts.ts | 37 +++++++++---- lib/main/typescript_editor_pane.ts | 65 ++++++++++++---------- lib/main/utils/dom.ts | 68 ++++++++++++++++++++++++ lib/tsconfig.json | 3 +- lib/typings/jsx.d.ts | 3 ++ lib/typings/status_bar.d.ts | 17 ++++++ package.json | 6 +++ 14 files changed, 322 insertions(+), 55 deletions(-) create mode 100644 dist/main/atom/components/statusBar.js create mode 100644 dist/main/atom/components/statusPanel.js create mode 100644 dist/main/utils/dom.js create mode 100644 lib/main/atom/components/statusPanel.tsx create mode 100644 lib/main/utils/dom.ts create mode 100644 lib/typings/jsx.d.ts create mode 100644 lib/typings/status_bar.d.ts diff --git a/dist/client/client.js b/dist/client/client.js index 8bfda4252..f533b8822 100644 --- a/dist/client/client.js +++ b/dist/client/client.js @@ -1,5 +1,4 @@ "use strict"; -const tslib_1 = require("tslib"); const child_process_1 = require("child_process"); const stream_1 = require("stream"); const byline = require("byline"); @@ -143,7 +142,6 @@ class TypescriptServiceClient { } } } -exports.TypescriptServiceClient = TypescriptServiceClient; TypescriptServiceClient.commandWithResponse = { compileOnSaveAffectedFileList: true, compileOnSaveEmitFile: true, @@ -153,6 +151,7 @@ TypescriptServiceClient.commandWithResponse = { quickinfo: true, reload: true, }; +exports.TypescriptServiceClient = TypescriptServiceClient; function isEvent(res) { return res.type === "event"; } diff --git a/dist/main/atom/components/statusBar.js b/dist/main/atom/components/statusBar.js new file mode 100644 index 000000000..4bbe21009 --- /dev/null +++ b/dist/main/atom/components/statusBar.js @@ -0,0 +1,16 @@ +"use strict"; +const tslib_1 = require("tslib"); +class StatusPanel extends HTMLElement { + createdCallback() { + console.log("created"); + this.innerHTML = "Ay karamba!"; + } + attachedCallback() { + console.log("attached"); + } + attributeChangedCallback() { + console.log("attrs changed", arguments); + } +} +exports.StatusPanel = StatusPanel; +document.registerElement('ts-status-panel', StatusPanel); diff --git a/dist/main/atom/components/statusPanel.js b/dist/main/atom/components/statusPanel.js new file mode 100644 index 000000000..d19a28757 --- /dev/null +++ b/dist/main/atom/components/statusPanel.js @@ -0,0 +1,28 @@ +"use strict"; +const tslib_1 = require("tslib"); +const dom = require("../../utils/dom"); +class StatusPanel extends HTMLElement { + createdCallback() { + this.appendChild(dom.createElement("div", { className: "inline-block ts-status-version" }, "2.2.0-15072987")); + this.appendChild(dom.createElement("div", { className: "inline-block ts-status-pending" }, + dom.createElement("span", { className: "ts-status-pending-count" }, "3"), + dom.createElement("span", { className: "loading loading-spinner-tiny inline-block", style: { marginLeft: 5 } }))); + } + attachedCallback() { + console.log("attached"); + } + attributeChangedCallback() { + console.log("attrs changed", arguments); + } + show() { + this.style.display = "block"; + } + hide() { + this.style.display = "none"; + } + static create() { + return document.createElement("ts-status-panel"); + } +} +exports.StatusPanel = StatusPanel; +document.registerElement('ts-status-panel', StatusPanel); diff --git a/dist/main/atomts.js b/dist/main/atomts.js index fa9b893d9..772ebd09d 100644 --- a/dist/main/atomts.js +++ b/dist/main/atomts.js @@ -7,27 +7,32 @@ const atom_1 = require("atom"); const lodash_1 = require("lodash"); const error_pusher_1 = require("./error_pusher"); const typescript_editor_pane_1 = require("./typescript_editor_pane"); +const statusPanel_1 = require("./atom/components/statusPanel"); const atomConfig = require("./atom/atomConfig"); const autoCompleteProvider = require("./atom/autoCompleteProvider"); const commands = require("./atom/commands/commands"); const hyperclickProvider = require("../hyperclickProvider"); -const mainPanelView_1 = require("./atom/views/mainPanelView"); const renameView = require("./atom/views/renameView"); const tsconfig = require("tsconfig/dist/tsconfig"); const subscriptions = new atom_1.CompositeDisposable(); exports.clientResolver = new clientResolver_1.ClientResolver(); exports.config = atomConfig.schema; let linter; +let statusBar; function activate(state) { require('atom-package-deps').install('atom-typescript').then(() => { - const mainPanel = mainPanelView_1.attach(); - const errorPusher = new error_pusher_1.ErrorPusher(); - mainPanel.hide(); - exports.clientResolver.on("pendingRequestsChange", () => { - const pending = Object.keys(exports.clientResolver.clients) - .map(serverPath => exports.clientResolver.clients[serverPath].pending); - mainPanel.view.updatePendingRequests([].concat.apply([], pending)); + let statusPriority = 100; + for (const panel of statusBar.getRightTiles()) { + if (panel.getItem().tagName === "GRAMMAR-SELECTOR-STATUS") { + statusPriority = panel.getPriority() - 1; + } + } + const statusPanel = statusPanel_1.StatusPanel.create(); + statusBar.addRightTile({ + item: statusPanel, + priority: statusPriority }); + const errorPusher = new error_pusher_1.ErrorPusher(); if (linter) { errorPusher.setLinter(linter); exports.clientResolver.on("diagnostics", ({ type, serverPath, filePath, diagnostics }) => { @@ -47,7 +52,6 @@ function activate(state) { }, 50); subscriptions.add(atom.workspace.observeTextEditors((editor) => { panes.push(new typescript_editor_pane_1.TypescriptEditorPane(editor, { - mainPanel, onDispose(pane) { if (activePane === pane) { activePane = null; @@ -93,6 +97,10 @@ function consumeLinter(registry) { console.log("linter is", linter); } exports.consumeLinter = consumeLinter; +function consumeStatusBar(_statusBar) { + statusBar = _statusBar; +} +exports.consumeStatusBar = consumeStatusBar; function provide() { return [autoCompleteProvider.provider]; } diff --git a/dist/main/typescript_editor_pane.js b/dist/main/typescript_editor_pane.js index 82c02f7b9..d407d96fd 100644 --- a/dist/main/typescript_editor_pane.js +++ b/dist/main/typescript_editor_pane.js @@ -19,7 +19,6 @@ class TypescriptEditorPane { this.activeAt = Date.now(); this.isActive = true; if (this.isTypescript && this.filePath) { - this.mainPanel.show(); if (this.client) { this.client.executeGetErr({ files: [this.filePath], @@ -27,11 +26,9 @@ class TypescriptEditorPane { }); } } - this.mainPanel.view.setTsconfigInUse(this.configFile); }; this.onDeactivated = () => { this.isActive = false; - this.mainPanel.hide(); }; this.onDidChange = diff => { if (this.isOpen) { @@ -69,7 +66,7 @@ class TypescriptEditorPane { }).catch(() => null); }; this.onDidSave = (event) => tslib_1.__awaiter(this, void 0, void 0, function* () { - console.log("saved", this.editor.getPath()); + console.log("saved", this.filePath); if (this.filePath !== event.path) { console.log("file path changed to", event.path); this.client = yield atomts_1.clientResolver.get(event.path); @@ -89,6 +86,7 @@ class TypescriptEditorPane { } }); this.onDidStopChanging = () => { + console.log("did stop changing", this.filePath); if (this.isTypescript && this.filePath) { this.client.executeGetErr({ files: [this.filePath], @@ -97,7 +95,6 @@ class TypescriptEditorPane { } }; this.onSave = opts.onSave; - this.mainPanel = opts.mainPanel; this.editor = editor; this.filePath = editor.getPath(); this.isTypescript = isTypescriptGrammar(editor.getGrammar()); @@ -130,7 +127,6 @@ class TypescriptEditorPane { }).then(result => { this.configFile = result.body.configFileName; if (this.isActive) { - this.mainPanel.view.setTsconfigInUse(this.configFile); } }, error => null); } diff --git a/dist/main/utils/dom.js b/dist/main/utils/dom.js new file mode 100644 index 000000000..e401796cd --- /dev/null +++ b/dist/main/utils/dom.js @@ -0,0 +1,58 @@ +"use strict"; +function createElement(name, props, ...children) { + if (typeof name !== "string") { + throw new Error("String tag name expected"); + } + const element = document.createElement(name); + if (props) { + for (let attr in props) { + if (attr === "ref") { + if (typeof props[attr] !== "function") { + throw new Error("Ref attribute value should be a function"); + } + var ref = props[attr]; + continue; + } + else if (attr === "key") { + continue; + } + const value = props[attr]; + if (attr.startsWith("on") && attr[2] && attr[2] === attr[2].toUpperCase()) { + attr = attr.toLowerCase(); + } + else if (attr === "style") { + if (typeof value === "object" && value) { + const style = element.style; + for (const prop in value) { + if (typeof value[prop] === "number") { + style[prop] = value[prop] + "px"; + } + else { + style[prop] = value[prop]; + } + } + } + break; + } + element[attr] = value; + } + } + for (const child of children) { + if (typeof child === "string" || typeof child === "number") { + element.appendChild(document.createTextNode(child.toString())); + } + else if (child instanceof HTMLElement) { + element.appendChild(child); + } + else if (child === null || child === undefined) { + } + else { + throw new Error("Unknown child type: " + child); + } + } + if (ref) { + ref(element); + } + return element; +} +exports.createElement = createElement; diff --git a/lib/main/atom/components/statusPanel.tsx b/lib/main/atom/components/statusPanel.tsx new file mode 100644 index 000000000..d290fdc8e --- /dev/null +++ b/lib/main/atom/components/statusPanel.tsx @@ -0,0 +1,39 @@ +import * as dom from "../../utils/dom" + +export class StatusPanel extends HTMLElement { + createdCallback() { + this.appendChild(
    2.2.0-15072987
    ) + this.appendChild( +
    + 3 + + +
    + ) + } + + attachedCallback() { + console.log("attached") + } + + attributeChangedCallback() { + console.log("attrs changed", arguments) + } + + show() { + this.style.display = "block" + } + + hide() { + this.style.display = "none" + } + + static create() { + return document.createElement("ts-status-panel") as StatusPanel + } +} + +(document as any).registerElement('ts-status-panel', StatusPanel) diff --git a/lib/main/atomts.ts b/lib/main/atomts.ts index 39810b8b9..eb5a590dc 100644 --- a/lib/main/atomts.ts +++ b/lib/main/atomts.ts @@ -10,14 +10,15 @@ import {CompositeDisposable} from "atom" import {debounce} from "lodash" import {ErrorPusher} from "./error_pusher" import {LinterRegistry, Linter} from "../typings/linter" +import {StatusBar} from "../typings/status_bar" import {TypescriptEditorPane} from "./typescript_editor_pane" +import {StatusPanel} from "./atom/components/statusPanel" import * as atomConfig from './atom/atomConfig' // import * as atomUtils from './atom/atomUtils' import * as autoCompleteProvider from './atom/autoCompleteProvider' import * as commands from "./atom/commands/commands" // import * as fs from 'fs' import * as hyperclickProvider from "../hyperclickProvider" -import {attach as attachMainPanel} from "./atom/views/mainPanelView" // import * as path from 'path' import * as renameView from './atom/views/renameView' import * as tsconfig from "tsconfig/dist/tsconfig" @@ -26,25 +27,38 @@ import * as tsconfig from "tsconfig/dist/tsconfig" const subscriptions = new CompositeDisposable() export const clientResolver = new ClientResolver() export const config = atomConfig.schema + let linter: Linter +let statusBar: StatusBar interface PackageState {} export function activate(state: PackageState) { require('atom-package-deps').install('atom-typescript').then(() => { - const mainPanel = attachMainPanel() - const errorPusher = new ErrorPusher() - - mainPanel.hide() + let statusPriority = 100 + for (const panel of statusBar.getRightTiles()) { + if (panel.getItem().tagName === "GRAMMAR-SELECTOR-STATUS") { + statusPriority = panel.getPriority() - 1 + } + } - clientResolver.on("pendingRequestsChange", () => { - const pending = Object.keys(clientResolver.clients) - .map(serverPath => clientResolver.clients[serverPath].pending) + const statusPanel = StatusPanel.create() - mainPanel.view.updatePendingRequests([].concat.apply([], pending)) + statusBar.addRightTile({ + item: statusPanel, + priority: statusPriority }) + const errorPusher = new ErrorPusher() + + // clientResolver.on("pendingRequestsChange", () => { + // const pending = Object.keys(clientResolver.clients) + // .map(serverPath => clientResolver.clients[serverPath].pending) + // + // mainPanel.view.updatePendingRequests([].concat.apply([], pending)) + // }) + if (linter) { errorPusher.setLinter(linter) @@ -75,7 +89,6 @@ export function activate(state: PackageState) { subscriptions.add(atom.workspace.observeTextEditors((editor: AtomCore.IEditor) => { panes.push(new TypescriptEditorPane(editor, { - mainPanel, onDispose(pane) { if (activePane === pane) { activePane = null @@ -129,6 +142,10 @@ export function consumeLinter(registry: LinterRegistry) { console.log("linter is", linter) } +export function consumeStatusBar(_statusBar) { + statusBar = _statusBar +} + // Registering an autocomplete provider export function provide() { return [autoCompleteProvider.provider]; diff --git a/lib/main/typescript_editor_pane.ts b/lib/main/typescript_editor_pane.ts index 83af5a97d..59f8b04c4 100644 --- a/lib/main/typescript_editor_pane.ts +++ b/lib/main/typescript_editor_pane.ts @@ -2,7 +2,6 @@ import {$} from "atom-space-pen-views" import {basename} from "path" import {clientResolver} from "./atomts" import {CompositeDisposable} from "atom" -import {MainPanel} from "./atom/views/mainPanelView" import {spanToRange} from "./utils/tsUtil" import {TypescriptServiceClient} from "../client/client" import * as tooltipManager from './atom/tooltipManager' @@ -15,21 +14,20 @@ type onChangeObserver = (diff: { }) => any interface PaneOptions { - mainPanel: MainPanel + onDispose: (pane: TypescriptEditorPane) => any onSave: (pane: TypescriptEditorPane) => any } export class TypescriptEditorPane implements AtomCore.Disposable { activeAt: number - - onSave: (pane: TypescriptEditorPane) => any client: TypescriptServiceClient + configFile: string = "" filePath: string - - isTypescript = false + isActive = false isTSConfig = false - - mainPanel: MainPanel + isTypescript = false + onDispose: (pane: TypescriptEditorPane) => any + onSave: (pane: TypescriptEditorPane) => any private isOpen = false @@ -39,7 +37,6 @@ export class TypescriptEditorPane implements AtomCore.Disposable { constructor(editor: AtomCore.IEditor, opts: PaneOptions) { this.onSave = opts.onSave - this.mainPanel = opts.mainPanel this.editor = editor this.filePath = editor.getPath() @@ -75,26 +72,39 @@ export class TypescriptEditorPane implements AtomCore.Disposable { }) this.isOpen = true - this.updatePanelConfig() + + this.client.executeProjectInfo({ + needFileNameList: false, + file: this.filePath + }).then(result => { + this.configFile = result.body.configFileName + + if (this.isActive) { + // this.mainPanel.view.setTsconfigInUse(this.configFile) + } + }, error => null) } }) this.setupTooltipView() } - async dispose() { + dispose() { this.subscriptions.dispose() if (this.isOpen) { this.client.executeClose({file: this.filePath}) } + + this.onDispose(this) } onActivated = () => { this.activeAt = Date.now() + this.isActive = true if (this.isTypescript && this.filePath) { - this.mainPanel.show() + // this.mainPanel.show() if (this.client) { // The first activation might happen before we even have a client @@ -104,10 +114,13 @@ export class TypescriptEditorPane implements AtomCore.Disposable { }) } } + + // this.mainPanel.view.setTsconfigInUse(this.configFile) } onDeactivated = () => { - this.mainPanel.hide() + this.isActive = false + // this.mainPanel.hide() } onDidChange: onChangeObserver = diff => { @@ -152,7 +165,7 @@ export class TypescriptEditorPane implements AtomCore.Disposable { onDidSave = async event => { // Observe editors saving - console.log("saved", this.editor.getPath()) + console.log("saved", this.filePath) if (this.filePath !== event.path) { console.log("file path changed to", event.path) @@ -164,9 +177,20 @@ export class TypescriptEditorPane implements AtomCore.Disposable { if (this.onSave) { this.onSave(this) } + + const result = await this.client.executeCompileOnSaveAffectedFileList({ + file: this.filePath + }) + + for (const project of result.body) { + for (const file of project.fileNames) { + this.client.executeCompileOnSaveEmitFile({file}) + } + } } onDidStopChanging = () => { + console.log("did stop changing", this.filePath) if (this.isTypescript && this.filePath) { this.client.executeGetErr({ files: [this.filePath], @@ -181,19 +205,6 @@ export class TypescriptEditorPane implements AtomCore.Disposable { const editorView = $(atom.views.getView(this.editor)) tooltipManager.attach(editorView, this.editor) } - - async updatePanelConfig() { - let configPath = "" - try { - const result = await this.client.executeProjectInfo({ - needFileNameList: false, - file: this.filePath - }) - configPath = result.body.configFileName - } catch (error) {} - - this.mainPanel.view.setTsconfigInUse(configPath) - } } function isTypescriptGrammar(grammar: AtomCore.IGrammar): boolean { diff --git a/lib/main/utils/dom.ts b/lib/main/utils/dom.ts new file mode 100644 index 000000000..4c06cc92a --- /dev/null +++ b/lib/main/utils/dom.ts @@ -0,0 +1,68 @@ +interface Props { + [key: string]: any +} + +// A createElement function that matches the signature of React.createElements, but synchronously +// creates DOM elements. Useful to quickly create DOM nodes when used with JSX and reactNamespace +// compiler option. +export function createElement(name: string, props: Props, ...children) { + if (typeof name !== "string") { + throw new Error("String tag name expected") + } + + const element = document.createElement(name) + + if (props) { + for (let attr in props) { + // Handle special cases like ref and key + if (attr === "ref") { + if (typeof props[attr] !== "function") { + throw new Error("Ref attribute value should be a function") + } + var ref = props[attr] + continue + } else if (attr === "key") { + continue + } + + const value = props[attr] + + if (attr.startsWith("on") && attr[2] && attr[2] === attr[2].toUpperCase()) { + // This is PROBABLY an event handle so we just lowercase the attr name + attr = attr.toLowerCase() + } else if (attr === "style") { + if (typeof value === "object" && value) { + const style = element.style + for (const prop in value) { + if (typeof value[prop] === "number") { + style[prop] = value[prop] + "px" + } else { + style[prop] = value[prop] + } + } + } + + break + } + + element[attr] = value + } + } + + for (const child of children) { + if (typeof child === "string" || typeof child === "number") { + element.appendChild(document.createTextNode(child.toString())) + } else if (child instanceof HTMLElement) { + element.appendChild(child) + } else if (child === null || child === undefined) { + // do nothing + } else { + throw new Error("Unknown child type: " + child) + } + } + + if (ref) { + ref(element) + } + return element +} diff --git a/lib/tsconfig.json b/lib/tsconfig.json index e56ec8774..1884e93a8 100644 --- a/lib/tsconfig.json +++ b/lib/tsconfig.json @@ -13,7 +13,8 @@ "outDir": "../dist", "sourceMap": false, "jsx": "react", - "types": [] + "reactNamespace": "dom", + "types": ["react"] }, "atom": { "formatOnSave": false diff --git a/lib/typings/jsx.d.ts b/lib/typings/jsx.d.ts new file mode 100644 index 000000000..bd1a44062 --- /dev/null +++ b/lib/typings/jsx.d.ts @@ -0,0 +1,3 @@ +declare namespace JSX { + interface Element extends HTMLElement {} +} 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/package.json b/package.json index 18e4ed11b..02a83c71d 100644 --- a/package.json +++ b/package.json @@ -20,6 +20,11 @@ "versions": { "^1.0.0": "consumeLinter" } + }, + "status-bar": { + "versions": { + "^1.0.0": "consumeStatusBar" + } } }, "providedServices": { @@ -47,6 +52,7 @@ "@types/atom": "0.0.35", "@types/byline": "^4.2.31", "@types/lodash": "4.14.41", + "@types/react": "0.14.52", "@types/resolve": "0.0.4", "atom-package-deps": "^2.0.3", "atom-space-pen-views": "^2.0.4", From 8a9baf2c2a6c175608c3fce88698f0732747540d Mon Sep 17 00:00:00 2001 From: Guntars Asmanis-Graham Date: Fri, 9 Dec 2016 15:22:02 -0500 Subject: [PATCH 24/70] stuiff --- dist/main/atom/components/statusPanel.js | 3 ++- dist/main/atom/views/mainPanelView.js | 1 - lib/main/atom/components/statusPanel.tsx | 11 +++++++++++ lib/main/utils/dom.ts | 4 ++-- lib/tsconfig.json | 4 ++-- lib/typings/jsx.d.ts | 3 --- package.json | 2 +- 7 files changed, 18 insertions(+), 10 deletions(-) diff --git a/dist/main/atom/components/statusPanel.js b/dist/main/atom/components/statusPanel.js index d19a28757..993c7735f 100644 --- a/dist/main/atom/components/statusPanel.js +++ b/dist/main/atom/components/statusPanel.js @@ -1,6 +1,7 @@ "use strict"; -const tslib_1 = require("tslib"); const dom = require("../../utils/dom"); +let span = dom.createElement("span", { ref: el => console.log("el be", el) }); +console.log("x", span); class StatusPanel extends HTMLElement { createdCallback() { this.appendChild(dom.createElement("div", { className: "inline-block ts-status-version" }, "2.2.0-15072987")); diff --git a/dist/main/atom/views/mainPanelView.js b/dist/main/atom/views/mainPanelView.js index 0ca3667f2..e6839da09 100644 --- a/dist/main/atom/views/mainPanelView.js +++ b/dist/main/atom/views/mainPanelView.js @@ -1,5 +1,4 @@ "use strict"; -const tslib_1 = require("tslib"); const view = require("./view"); const lineMessageView = require("./lineMessageView"); const atomUtils = require("../atomUtils"); diff --git a/lib/main/atom/components/statusPanel.tsx b/lib/main/atom/components/statusPanel.tsx index d290fdc8e..d29e0a47a 100644 --- a/lib/main/atom/components/statusPanel.tsx +++ b/lib/main/atom/components/statusPanel.tsx @@ -1,5 +1,16 @@ import * as dom from "../../utils/dom" +declare global { + namespace JSX { + interface Element extends HTMLElement {} + } +} + +let span = console.log("el be", el) }> + + +console.log("x", span) + export class StatusPanel extends HTMLElement { createdCallback() { this.appendChild(
    2.2.0-15072987
    ) diff --git a/lib/main/utils/dom.ts b/lib/main/utils/dom.ts index 4c06cc92a..93c210bd1 100644 --- a/lib/main/utils/dom.ts +++ b/lib/main/utils/dom.ts @@ -5,7 +5,7 @@ interface Props { // A createElement function that matches the signature of React.createElements, but synchronously // creates DOM elements. Useful to quickly create DOM nodes when used with JSX and reactNamespace // compiler option. -export function createElement(name: string, props: Props, ...children) { +export function createElement(name: string, props: Props, ...children): string { if (typeof name !== "string") { throw new Error("String tag name expected") } @@ -64,5 +64,5 @@ export function createElement(name: string, props: Props, ...children) { if (ref) { ref(element) } - return element + return element as any } diff --git a/lib/tsconfig.json b/lib/tsconfig.json index 1884e93a8..7c32fae4e 100644 --- a/lib/tsconfig.json +++ b/lib/tsconfig.json @@ -13,8 +13,8 @@ "outDir": "../dist", "sourceMap": false, "jsx": "react", - "reactNamespace": "dom", - "types": ["react"] + "types": ["react"], + "reactNamespace": "dom" }, "atom": { "formatOnSave": false diff --git a/lib/typings/jsx.d.ts b/lib/typings/jsx.d.ts index bd1a44062..e69de29bb 100644 --- a/lib/typings/jsx.d.ts +++ b/lib/typings/jsx.d.ts @@ -1,3 +0,0 @@ -declare namespace JSX { - interface Element extends HTMLElement {} -} diff --git a/package.json b/package.json index 02a83c71d..030329215 100644 --- a/package.json +++ b/package.json @@ -69,7 +69,7 @@ "resolve": "1.1.7", "tsconfig": "^2.2.0", "tslib": "1.2.0", - "typescript": "2.2.0-dev.20161130" + "typescript": "2.1.4" }, "devDependencies": { "@types/cson": "0.0.30", From efda87fcab2ab9047e2f234e72791cd503d88c92 Mon Sep 17 00:00:00 2001 From: Guntars Asmanis-Graham Date: Sat, 17 Dec 2016 16:00:20 -0500 Subject: [PATCH 25/70] Show TS version, project path and pending requests in status bar --- dist/client/client.js | 3 +- dist/client/clientResolver.js | 30 +++--- dist/main/atom/components/statusPanel.js | 75 +++++++++++++-- dist/main/atomts.js | 9 +- dist/main/typescript_editor_pane.js | 15 ++- lib/client/client.ts | 4 +- lib/client/clientResolver.ts | 37 +++++--- lib/main/atom/components/statusPanel.tsx | 113 +++++++++++++++++++---- lib/main/atomts.ts | 16 ++-- lib/main/typescript_editor_pane.ts | 25 +++-- lib/main/utils/dom.ts | 68 -------------- package.json | 3 +- 12 files changed, 250 insertions(+), 148 deletions(-) delete mode 100644 lib/main/utils/dom.ts diff --git a/dist/client/client.js b/dist/client/client.js index f533b8822..c3dc7f994 100644 --- a/dist/client/client.js +++ b/dist/client/client.js @@ -3,7 +3,7 @@ const child_process_1 = require("child_process"); const stream_1 = require("stream"); const byline = require("byline"); class TypescriptServiceClient { - constructor(tsServerPath) { + constructor(tsServerPath, version) { this.callbacks = {}; this.listeners = {}; this.seq = 0; @@ -28,6 +28,7 @@ class TypescriptServiceClient { } }; this.tsServerPath = tsServerPath; + this.version = version; } executeChange(args) { this.execute("change", args); diff --git a/dist/client/clientResolver.js b/dist/client/clientResolver.js index 107ad4f24..99d79e2d4 100644 --- a/dist/client/clientResolver.js +++ b/dist/client/clientResolver.js @@ -2,8 +2,11 @@ const client_1 = require("./client"); const events = require("events"); const path = require("path"); -const nodeResolve = require("resolve"); -const defaultServerPath = require.resolve("typescript/bin/tsserver"); +const resolve_1 = require("resolve"); +const defaultServer = { + serverPath: require.resolve("typescript/bin/tsserver"), + version: require("typescript").version +}; class ClientResolver extends events.EventEmitter { constructor() { super(...arguments); @@ -14,13 +17,13 @@ class ClientResolver extends events.EventEmitter { } get(filePath) { return resolveServer(filePath) - .catch(() => defaultServerPath) - .then(serverPath => { + .catch(() => defaultServer) + .then(({ serverPath, version }) => { if (this.clients[serverPath]) { return this.clients[serverPath].client; } const entry = this.clients[serverPath] = { - client: new client_1.TypescriptServiceClient(serverPath), + client: new client_1.TypescriptServiceClient(serverPath, version), pending: [], }; entry.client.startServer(); @@ -46,15 +49,14 @@ class ClientResolver extends events.EventEmitter { exports.ClientResolver = ClientResolver; function resolveServer(sourcePath) { const basedir = path.dirname(sourcePath); - return new Promise((resolve, reject) => { - nodeResolve("typescript/bin/tsserver", { basedir }, (err, resolvedPath) => { - if (err) { - reject(err); - } - else { - resolve(resolvedPath); - } - }); + 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; diff --git a/dist/main/atom/components/statusPanel.js b/dist/main/atom/components/statusPanel.js index 993c7735f..db26759b5 100644 --- a/dist/main/atom/components/statusPanel.js +++ b/dist/main/atom/components/statusPanel.js @@ -1,13 +1,28 @@ "use strict"; -const dom = require("../../utils/dom"); -let span = dom.createElement("span", { ref: el => console.log("el be", el) }); -console.log("x", span); +const dom = require("jsx-render-dom"); +const path_1 = require("path"); +const atomUtils_1 = require("../atomUtils"); class StatusPanel extends HTMLElement { createdCallback() { - this.appendChild(dom.createElement("div", { className: "inline-block ts-status-version" }, "2.2.0-15072987")); - this.appendChild(dom.createElement("div", { className: "inline-block ts-status-pending" }, - dom.createElement("span", { className: "ts-status-pending-count" }, "3"), - dom.createElement("span", { className: "loading loading-spinner-tiny inline-block", style: { marginLeft: 5 } }))); + 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(); + } }) + ]; + for (const node of nodes) { + this.appendChild(node); + } + this.setVersion(null); + this.setPending([]); + this.setTsConfigPath(null); } attachedCallback() { console.log("attached"); @@ -15,6 +30,52 @@ class StatusPanel extends HTMLElement { attributeChangedCallback() { console.log("attrs changed", arguments); } + dispose() { + this.remove(); + } + openConfigPath() { + if (this.configPath && !this.configPath.startsWith("/dev/null")) { + atomUtils_1.openFile(this.configPath); + } + else { + atom.notifications.addInfo("No tsconfig for current file"); + } + } + setTsConfigPath(configPath) { + this.configPath = configPath; + if (configPath) { + this.configPathContainer.textContent = configPath.startsWith("/dev/null") ? "No project" : + path_1.dirname(atomUtils_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"); + } + } + showPendingRequests() { + if (this.pendingRequests) { + atom.notifications.addInfo("Pending Requests:
    - " + this.pendingRequests.join("
    - ")); + } + } show() { this.style.display = "block"; } diff --git a/dist/main/atomts.js b/dist/main/atomts.js index 772ebd09d..884a78f2d 100644 --- a/dist/main/atomts.js +++ b/dist/main/atomts.js @@ -14,6 +14,7 @@ const commands = require("./atom/commands/commands"); const hyperclickProvider = require("../hyperclickProvider"); const renameView = require("./atom/views/renameView"); const tsconfig = require("tsconfig/dist/tsconfig"); +const lodash_2 = require("lodash"); const subscriptions = new atom_1.CompositeDisposable(); exports.clientResolver = new clientResolver_1.ClientResolver(); exports.config = atomConfig.schema; @@ -32,7 +33,12 @@ function activate(state) { item: statusPanel, priority: statusPriority }); + subscriptions.add(statusPanel); const errorPusher = new error_pusher_1.ErrorPusher(); + 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, serverPath, filePath, diagnostics }) => { @@ -58,7 +64,8 @@ function activate(state) { } panes.splice(panes.indexOf(pane), 1); }, - onSave + onSave, + statusPanel, })); })); let activePane = panes.find(pane => pane.editor === atom.workspace.getActiveTextEditor()); diff --git a/dist/main/typescript_editor_pane.js b/dist/main/typescript_editor_pane.js index d407d96fd..01f5d894e 100644 --- a/dist/main/typescript_editor_pane.js +++ b/dist/main/typescript_editor_pane.js @@ -24,8 +24,10 @@ class TypescriptEditorPane { files: [this.filePath], delay: 100 }); + this.opts.statusPanel.setVersion(this.client.version); } } + this.opts.statusPanel.setTsConfigPath(this.configFile); }; this.onDeactivated = () => { this.isActive = false; @@ -73,8 +75,8 @@ class TypescriptEditorPane { this.filePath = event.path; this.isTSConfig = path_1.basename(this.filePath) === "tsconfig.json"; } - if (this.onSave) { - this.onSave(this); + if (this.opts.onSave) { + this.opts.onSave(this); } const result = yield this.client.executeCompileOnSaveAffectedFileList({ file: this.filePath @@ -94,9 +96,9 @@ class TypescriptEditorPane { }); } }; - this.onSave = opts.onSave; this.editor = editor; this.filePath = editor.getPath(); + this.opts = opts; this.isTypescript = isTypescriptGrammar(editor.getGrammar()); this.subscriptions.add(editor.onDidChangeGrammar(grammar => { this.isTypescript = isTypescriptGrammar(grammar); @@ -104,13 +106,15 @@ class TypescriptEditorPane { if (this.filePath) { this.isTSConfig = path_1.basename(this.filePath) === "tsconfig.json"; } - console.log("opened", this.filePath); atomts_1.clientResolver.get(this.filePath).then(client => { this.client = client; this.subscriptions.add(editor.buffer.onDidChange(this.onDidChange)); this.subscriptions.add(editor.onDidChangeCursorPosition(this.onDidChangeCursorPosition)); this.subscriptions.add(editor.onDidSave(this.onDidSave)); this.subscriptions.add(editor.onDidStopChanging(this.onDidStopChanging)); + if (this.isActive) { + this.opts.statusPanel.setVersion(this.client.version); + } if (this.isTypescript && this.filePath) { this.client.executeOpen({ file: this.filePath, @@ -127,6 +131,7 @@ class TypescriptEditorPane { }).then(result => { this.configFile = result.body.configFileName; if (this.isActive) { + this.opts.statusPanel.setTsConfigPath(this.configFile); } }, error => null); } @@ -138,7 +143,7 @@ class TypescriptEditorPane { if (this.isOpen) { this.client.executeClose({ file: this.filePath }); } - this.onDispose(this); + this.opts.onDispose(this); } setupTooltipView() { const editorView = atom_space_pen_views_1.$(atom.views.getView(this.editor)); diff --git a/lib/client/client.ts b/lib/client/client.ts index 453c05227..59f4a35c5 100644 --- a/lib/client/client.ts +++ b/lib/client/client.ts @@ -29,9 +29,11 @@ export class TypescriptServiceClient { /** Path to the tsserver executable */ readonly tsServerPath: string + readonly version: string - constructor(tsServerPath: string) { + constructor(tsServerPath: string, version) { this.tsServerPath = tsServerPath + this.version = version } static commandWithResponse = { diff --git a/lib/client/clientResolver.ts b/lib/client/clientResolver.ts index d14037a75..2096df685 100644 --- a/lib/client/clientResolver.ts +++ b/lib/client/clientResolver.ts @@ -1,7 +1,7 @@ import {TypescriptServiceClient as Client} from "./client" import * as events from "events" import * as path from "path" -import * as nodeResolve from "resolve" +import {sync as resolveSync} from "resolve" import {Diagnostic, DiagnosticEventBody, ConfigFileDiagnosticEventBody} from "typescript/lib/protocol" type DiagnosticTypes = "configFileDiag" | "semanticDiag" | "syntaxDiag" @@ -13,7 +13,15 @@ interface DiagnosticsPayload { type: DiagnosticTypes, } -const defaultServerPath = require.resolve("typescript/bin/tsserver") +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 @@ -37,14 +45,14 @@ export class ClientResolver extends events.EventEmitter { get(filePath: string): Promise { return resolveServer(filePath) - .catch(() => defaultServerPath) - .then(serverPath => { + .catch(() => defaultServer) + .then(({serverPath, version}) => { if (this.clients[serverPath]) { return this.clients[serverPath].client } const entry = this.clients[serverPath] = { - client: new Client(serverPath), + client: new Client(serverPath, version), pending: [], } @@ -73,17 +81,18 @@ export class ClientResolver extends events.EventEmitter { } } -export function resolveServer(sourcePath: string): Promise { +export function resolveServer(sourcePath: string): Promise { const basedir = path.dirname(sourcePath) - return new Promise((resolve, reject) => { - nodeResolve("typescript/bin/tsserver", {basedir}, (err, resolvedPath) => { - if (err) { - reject(err) - } else { - resolve(resolvedPath) - } - }) + 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 + } }) } diff --git a/lib/main/atom/components/statusPanel.tsx b/lib/main/atom/components/statusPanel.tsx index d29e0a47a..edf195ce6 100644 --- a/lib/main/atom/components/statusPanel.tsx +++ b/lib/main/atom/components/statusPanel.tsx @@ -1,29 +1,53 @@ -import * as dom from "../../utils/dom" +import * as dom from "jsx-render-dom" +import {dirname} from "path" +import { + getFilePathRelativeToAtomProject, + openFile, +} from "../atomUtils" -declare global { - namespace JSX { - interface Element extends HTMLElement {} - } -} - -let span = console.log("el be", el) }> +export class StatusPanel extends HTMLElement { + private pendingContainer: HTMLElement + private pendingCounter: HTMLElement + private pendingSpinner: HTMLElement + private configPathContainer: HTMLElement + private version: HTMLElement -console.log("x", span) + private configPath: string + private pendingRequests: string[] -export class StatusPanel extends HTMLElement { createdCallback() { - this.appendChild(
    2.2.0-15072987
    ) - this.appendChild( - - ) + , + this.configPathContainer = el } + className="inline-block" + href="" + onClick={ evt => { + evt.preventDefault() + this.openConfigPath() + }}/> + ] + + for (const node of nodes) { + this.appendChild(node) + } + + this.setVersion(null) + this.setPending([]) + this.setTsConfigPath(null) } attachedCallback() { @@ -34,6 +58,57 @@ export class StatusPanel extends HTMLElement { console.log("attrs changed", arguments) } + dispose() { + this.remove() + } + + openConfigPath() { + if (this.configPath && !this.configPath.startsWith("/dev/null")) { + openFile(this.configPath) + } else { + atom.notifications.addInfo("No tsconfig for current file") + } + } + + 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") + } + } + + 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") + } + } + + showPendingRequests() { + if (this.pendingRequests) { + atom.notifications.addInfo("Pending Requests:
    - " + this.pendingRequests.join("
    - ")) + } + } + show() { this.style.display = "block" } diff --git a/lib/main/atomts.ts b/lib/main/atomts.ts index eb5a590dc..f2a93a0fa 100644 --- a/lib/main/atomts.ts +++ b/lib/main/atomts.ts @@ -22,6 +22,7 @@ import * as hyperclickProvider from "../hyperclickProvider" // import * as path from 'path' import * as renameView from './atom/views/renameView' import * as tsconfig from "tsconfig/dist/tsconfig" +import {flatten, values} from "lodash" // globals const subscriptions = new CompositeDisposable() @@ -50,14 +51,14 @@ export function activate(state: PackageState) { priority: statusPriority }) + subscriptions.add(statusPanel) + const errorPusher = new ErrorPusher() - // clientResolver.on("pendingRequestsChange", () => { - // const pending = Object.keys(clientResolver.clients) - // .map(serverPath => clientResolver.clients[serverPath].pending) - // - // mainPanel.view.updatePendingRequests([].concat.apply([], pending)) - // }) + clientResolver.on("pendingRequestsChange", () => { + const pending = flatten(values(clientResolver.clients).map(cl => cl.pending)) + statusPanel.setPending(pending) + }) if (linter) { errorPusher.setLinter(linter) @@ -96,7 +97,8 @@ export function activate(state: PackageState) { panes.splice(panes.indexOf(pane), 1) }, - onSave + onSave, + statusPanel, })) })) diff --git a/lib/main/typescript_editor_pane.ts b/lib/main/typescript_editor_pane.ts index 59f8b04c4..a4765efa4 100644 --- a/lib/main/typescript_editor_pane.ts +++ b/lib/main/typescript_editor_pane.ts @@ -4,6 +4,7 @@ import {clientResolver} from "./atomts" import {CompositeDisposable} from "atom" import {spanToRange} from "./utils/tsUtil" import {TypescriptServiceClient} from "../client/client" +import {StatusPanel} from "./atom/components/statusPanel" import * as tooltipManager from './atom/tooltipManager' type onChangeObserver = (diff: { @@ -16,6 +17,7 @@ type onChangeObserver = (diff: { interface PaneOptions { onDispose: (pane: TypescriptEditorPane) => any onSave: (pane: TypescriptEditorPane) => any + statusPanel: StatusPanel } export class TypescriptEditorPane implements AtomCore.Disposable { @@ -26,9 +28,8 @@ export class TypescriptEditorPane implements AtomCore.Disposable { isActive = false isTSConfig = false isTypescript = false - onDispose: (pane: TypescriptEditorPane) => any - onSave: (pane: TypescriptEditorPane) => any + private opts: PaneOptions private isOpen = false readonly occurrenceMarkers: AtomCore.IDisplayBufferMarker[] = [] @@ -36,9 +37,9 @@ export class TypescriptEditorPane implements AtomCore.Disposable { readonly subscriptions = new CompositeDisposable() constructor(editor: AtomCore.IEditor, opts: PaneOptions) { - this.onSave = opts.onSave this.editor = editor this.filePath = editor.getPath() + this.opts = opts this.isTypescript = isTypescriptGrammar(editor.getGrammar()) @@ -50,8 +51,6 @@ export class TypescriptEditorPane implements AtomCore.Disposable { this.isTSConfig = basename(this.filePath) === "tsconfig.json" } - console.log("opened", this.filePath) - clientResolver.get(this.filePath).then(client => { this.client = client @@ -60,6 +59,10 @@ export class TypescriptEditorPane implements AtomCore.Disposable { this.subscriptions.add(editor.onDidSave(this.onDidSave)) this.subscriptions.add(editor.onDidStopChanging(this.onDidStopChanging)) + if (this.isActive) { + this.opts.statusPanel.setVersion(this.client.version) + } + if (this.isTypescript && this.filePath) { this.client.executeOpen({ file: this.filePath, @@ -80,7 +83,7 @@ export class TypescriptEditorPane implements AtomCore.Disposable { this.configFile = result.body.configFileName if (this.isActive) { - // this.mainPanel.view.setTsconfigInUse(this.configFile) + this.opts.statusPanel.setTsConfigPath(this.configFile) } }, error => null) } @@ -96,7 +99,7 @@ export class TypescriptEditorPane implements AtomCore.Disposable { this.client.executeClose({file: this.filePath}) } - this.onDispose(this) + this.opts.onDispose(this) } onActivated = () => { @@ -112,10 +115,12 @@ export class TypescriptEditorPane implements AtomCore.Disposable { files: [this.filePath], delay: 100 }) + + this.opts.statusPanel.setVersion(this.client.version) } } - // this.mainPanel.view.setTsconfigInUse(this.configFile) + this.opts.statusPanel.setTsConfigPath(this.configFile) } onDeactivated = () => { @@ -174,8 +179,8 @@ export class TypescriptEditorPane implements AtomCore.Disposable { this.isTSConfig = basename(this.filePath) === "tsconfig.json" } - if (this.onSave) { - this.onSave(this) + if (this.opts.onSave) { + this.opts.onSave(this) } const result = await this.client.executeCompileOnSaveAffectedFileList({ diff --git a/lib/main/utils/dom.ts b/lib/main/utils/dom.ts deleted file mode 100644 index 93c210bd1..000000000 --- a/lib/main/utils/dom.ts +++ /dev/null @@ -1,68 +0,0 @@ -interface Props { - [key: string]: any -} - -// A createElement function that matches the signature of React.createElements, but synchronously -// creates DOM elements. Useful to quickly create DOM nodes when used with JSX and reactNamespace -// compiler option. -export function createElement(name: string, props: Props, ...children): string { - if (typeof name !== "string") { - throw new Error("String tag name expected") - } - - const element = document.createElement(name) - - if (props) { - for (let attr in props) { - // Handle special cases like ref and key - if (attr === "ref") { - if (typeof props[attr] !== "function") { - throw new Error("Ref attribute value should be a function") - } - var ref = props[attr] - continue - } else if (attr === "key") { - continue - } - - const value = props[attr] - - if (attr.startsWith("on") && attr[2] && attr[2] === attr[2].toUpperCase()) { - // This is PROBABLY an event handle so we just lowercase the attr name - attr = attr.toLowerCase() - } else if (attr === "style") { - if (typeof value === "object" && value) { - const style = element.style - for (const prop in value) { - if (typeof value[prop] === "number") { - style[prop] = value[prop] + "px" - } else { - style[prop] = value[prop] - } - } - } - - break - } - - element[attr] = value - } - } - - for (const child of children) { - if (typeof child === "string" || typeof child === "number") { - element.appendChild(document.createTextNode(child.toString())) - } else if (child instanceof HTMLElement) { - element.appendChild(child) - } else if (child === null || child === undefined) { - // do nothing - } else { - throw new Error("Unknown child type: " + child) - } - } - - if (ref) { - ref(element) - } - return element as any -} diff --git a/package.json b/package.json index 030329215..f2dbe2bbd 100644 --- a/package.json +++ b/package.json @@ -65,7 +65,8 @@ "escape-html": "^1.0.1", "findup": "^0.1.5", "fuzzaldrin": "^2.1.0", - "lodash": "4.17.2", + "jsx-render-dom": "0.1.2", + "lodash": "^4.17.2", "resolve": "1.1.7", "tsconfig": "^2.2.0", "tslib": "1.2.0", From a8b1709aac936e545a0f767af1441eb8dcbd6c87 Mon Sep 17 00:00:00 2001 From: Guntars Asmanis-Graham Date: Sat, 17 Dec 2016 16:19:00 -0500 Subject: [PATCH 26/70] Debounce the pending dispaly --- dist/main/atom/components/statusPanel.js | 9 +++++++-- lib/main/atom/components/statusPanel.tsx | 11 +++++++++-- 2 files changed, 16 insertions(+), 4 deletions(-) diff --git a/dist/main/atom/components/statusPanel.js b/dist/main/atom/components/statusPanel.js index db26759b5..63b0b83db 100644 --- a/dist/main/atom/components/statusPanel.js +++ b/dist/main/atom/components/statusPanel.js @@ -21,7 +21,7 @@ class StatusPanel extends HTMLElement { this.appendChild(node); } this.setVersion(null); - this.setPending([]); + this.setPending([], true); this.setTsConfigPath(null); } attachedCallback() { @@ -61,7 +61,7 @@ class StatusPanel extends HTMLElement { this.version.classList.add("hide"); } } - setPending(pending) { + _setPending(pending) { this.pendingRequests = pending; if (pending.length) { this.pendingContainer.classList.remove("hide"); @@ -71,6 +71,11 @@ class StatusPanel extends HTMLElement { 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("
    - ")); diff --git a/lib/main/atom/components/statusPanel.tsx b/lib/main/atom/components/statusPanel.tsx index edf195ce6..2192735dd 100644 --- a/lib/main/atom/components/statusPanel.tsx +++ b/lib/main/atom/components/statusPanel.tsx @@ -15,6 +15,7 @@ export class StatusPanel extends HTMLElement { private configPath: string private pendingRequests: string[] + private pendingTimeout: any createdCallback() { const nodes = [ @@ -46,7 +47,7 @@ export class StatusPanel extends HTMLElement { } this.setVersion(null) - this.setPending([]) + this.setPending([], true) this.setTsConfigPath(null) } @@ -92,7 +93,7 @@ export class StatusPanel extends HTMLElement { } } - setPending(pending: string[]) { + private _setPending(pending: string[]) { this.pendingRequests = pending if (pending.length) { @@ -103,6 +104,12 @@ export class StatusPanel extends HTMLElement { } } + 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("
    - ")) From 2e867a3a7538a273e2aa4f6fab8a5e3fc0295747 Mon Sep 17 00:00:00 2001 From: Guntars Asmanis-Graham Date: Sat, 17 Dec 2016 17:26:27 -0500 Subject: [PATCH 27/70] Show emit status in the status panel --- dist/main/atom/components/statusPanel.js | 24 ++++++++++++++- dist/main/typescript_editor_pane.js | 30 +++++++++++++++++-- lib/main/atom/components/statusPanel.tsx | 27 ++++++++++++++++- lib/main/typescript_editor_pane.ts | 37 ++++++++++++++++++++++-- lib/tsconfig.json | 3 +- 5 files changed, 112 insertions(+), 9 deletions(-) diff --git a/dist/main/atom/components/statusPanel.js b/dist/main/atom/components/statusPanel.js index 63b0b83db..e11dfec66 100644 --- a/dist/main/atom/components/statusPanel.js +++ b/dist/main/atom/components/statusPanel.js @@ -15,7 +15,9 @@ class StatusPanel extends HTMLElement { 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 })) ]; for (const node of nodes) { this.appendChild(node); @@ -23,6 +25,7 @@ class StatusPanel extends HTMLElement { this.setVersion(null); this.setPending([], true); this.setTsConfigPath(null); + this.setBuildStatus(null); } attachedCallback() { console.log("attached"); @@ -41,6 +44,25 @@ class StatusPanel extends HTMLElement { 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"); + } + } setTsConfigPath(configPath) { this.configPath = configPath; if (configPath) { diff --git a/dist/main/typescript_editor_pane.js b/dist/main/typescript_editor_pane.js index 01f5d894e..37c9f5024 100644 --- a/dist/main/typescript_editor_pane.js +++ b/dist/main/typescript_editor_pane.js @@ -4,6 +4,7 @@ const atom_space_pen_views_1 = require("atom-space-pen-views"); const path_1 = require("path"); const atomts_1 = require("./atomts"); const atom_1 = require("atom"); +const lodash_1 = require("lodash"); const tsUtil_1 = require("./utils/tsUtil"); const tooltipManager = require("./atom/tooltipManager"); class TypescriptEditorPane { @@ -34,6 +35,7 @@ class TypescriptEditorPane { }; this.onDidChange = diff => { if (this.isOpen) { + this.opts.statusPanel.setBuildStatus(null); this.client.executeChange({ endLine: diff.oldRange.end.row + 1, endOffset: diff.oldRange.end.column + 1, @@ -67,6 +69,9 @@ class TypescriptEditorPane { } }).catch(() => null); }; + this.onDidDestroy = () => { + this.dispose(); + }; this.onDidSave = (event) => tslib_1.__awaiter(this, void 0, void 0, function* () { console.log("saved", this.filePath); if (this.filePath !== event.path) { @@ -81,10 +86,28 @@ class TypescriptEditorPane { const result = yield this.client.executeCompileOnSaveAffectedFileList({ file: this.filePath }); - for (const project of result.body) { - for (const file of project.fileNames) { - this.client.executeCompileOnSaveEmitFile({ file }); + this.opts.statusPanel.setBuildStatus(null); + console.log("Compile on Saving..."); + const fileNames = lodash_1.flatten(result.body.map(project => project.fileNames)); + if (fileNames.length === 0) { + return; + } + try { + const promises = fileNames.map(file => this.client.executeCompileOnSaveEmitFile({ file })); + const saved = yield Promise.all(promises); + if (!saved.every(res => res.body)) { + throw new Error("Some files failed to emit"); } + console.log("Saved....", saved); + this.opts.statusPanel.setBuildStatus({ + success: true + }); + } + catch (error) { + console.error("Save failed with error", error); + this.opts.statusPanel.setBuildStatus({ + success: false + }); } }); this.onDidStopChanging = () => { @@ -112,6 +135,7 @@ class TypescriptEditorPane { this.subscriptions.add(editor.onDidChangeCursorPosition(this.onDidChangeCursorPosition)); this.subscriptions.add(editor.onDidSave(this.onDidSave)); this.subscriptions.add(editor.onDidStopChanging(this.onDidStopChanging)); + this.subscriptions.add(editor.onDidDestroy(this.onDidDestroy)); if (this.isActive) { this.opts.statusPanel.setVersion(this.client.version); } diff --git a/lib/main/atom/components/statusPanel.tsx b/lib/main/atom/components/statusPanel.tsx index 2192735dd..8e8a9dce7 100644 --- a/lib/main/atom/components/statusPanel.tsx +++ b/lib/main/atom/components/statusPanel.tsx @@ -11,6 +11,8 @@ export class StatusPanel extends HTMLElement { private pendingCounter: HTMLElement private pendingSpinner: HTMLElement private configPathContainer: HTMLElement + private statusContainer: HTMLElement + private statusText: HTMLElement private version: HTMLElement private configPath: string @@ -39,7 +41,11 @@ export class StatusPanel extends HTMLElement { onClick={ evt => { evt.preventDefault() this.openConfigPath() - }}/> + }}/>, +
    this.statusContainer = el } + className="inline-block"> + this.statusText = el } /> +
    ] for (const node of nodes) { @@ -49,6 +55,7 @@ export class StatusPanel extends HTMLElement { this.setVersion(null) this.setPending([], true) this.setTsConfigPath(null) + this.setBuildStatus(null) } attachedCallback() { @@ -71,6 +78,24 @@ export class StatusPanel extends HTMLElement { } } + 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") + } + } + setTsConfigPath(configPath: string) { this.configPath = configPath diff --git a/lib/main/typescript_editor_pane.ts b/lib/main/typescript_editor_pane.ts index a4765efa4..761975fa8 100644 --- a/lib/main/typescript_editor_pane.ts +++ b/lib/main/typescript_editor_pane.ts @@ -2,6 +2,7 @@ import {$} from "atom-space-pen-views" import {basename} from "path" import {clientResolver} from "./atomts" import {CompositeDisposable} from "atom" +import {flatten} from "lodash" import {spanToRange} from "./utils/tsUtil" import {TypescriptServiceClient} from "../client/client" import {StatusPanel} from "./atom/components/statusPanel" @@ -58,6 +59,7 @@ export class TypescriptEditorPane implements AtomCore.Disposable { this.subscriptions.add(editor.onDidChangeCursorPosition(this.onDidChangeCursorPosition)) this.subscriptions.add(editor.onDidSave(this.onDidSave)) this.subscriptions.add(editor.onDidStopChanging(this.onDidStopChanging)) + this.subscriptions.add(editor.onDidDestroy(this.onDidDestroy)) if (this.isActive) { this.opts.statusPanel.setVersion(this.client.version) @@ -130,6 +132,8 @@ export class TypescriptEditorPane implements AtomCore.Disposable { onDidChange: onChangeObserver = diff => { if (this.isOpen) { + this.opts.statusPanel.setBuildStatus(null) + this.client.executeChange({ endLine: diff.oldRange.end.row+1, endOffset: diff.oldRange.end.column+1, @@ -168,6 +172,10 @@ export class TypescriptEditorPane implements AtomCore.Disposable { }).catch(() => null) } + onDidDestroy = () => { + this.dispose() + } + onDidSave = async event => { // Observe editors saving console.log("saved", this.filePath) @@ -187,10 +195,33 @@ export class TypescriptEditorPane implements AtomCore.Disposable { file: this.filePath }) - for (const project of result.body) { - for (const file of project.fileNames) { - this.client.executeCompileOnSaveEmitFile({file}) + this.opts.statusPanel.setBuildStatus(null) + + console.log("Compile on Saving...") + const fileNames = flatten(result.body.map(project => project.fileNames)) + + if (fileNames.length === 0) { + return + } + + try { + const promises = fileNames.map(file => this.client.executeCompileOnSaveEmitFile({file})) + const saved = await Promise.all(promises) + + if (!saved.every(res => res.body)) { + throw new Error("Some files failed to emit") } + + console.log("Saved....", saved) + this.opts.statusPanel.setBuildStatus({ + success: true + }) + + } catch (error) { + console.error("Save failed with error", error) + this.opts.statusPanel.setBuildStatus({ + success: false + }) } } diff --git a/lib/tsconfig.json b/lib/tsconfig.json index 7c32fae4e..75464d184 100644 --- a/lib/tsconfig.json +++ b/lib/tsconfig.json @@ -18,5 +18,6 @@ }, "atom": { "formatOnSave": false - } + }, + "compileOnSave": true } From 7743ef29c2f2182984c0c153cc7086f6c68ca925 Mon Sep 17 00:00:00 2001 From: Guntars Asmanis-Graham Date: Mon, 19 Dec 2016 10:53:34 -0500 Subject: [PATCH 28/70] Re-implement the autocomplete provider --- dist/client/client.js | 4 + dist/main/atom/atomUtils.js | 3 + dist/main/atom/autoCompleteProvider.js | 121 +++++--- dist/main/atom/commands/commands.js | 4 - dist/main/atom/components/statusPanel.js | 6 - dist/main/atomts.js | 6 +- keymaps/autocomplete-keymaps.cson | 3 - lib/client/client.ts | 4 + lib/main/atom/atomUtils.ts | 4 + lib/main/atom/autoCompleteProvider.ts | 365 ++++++++++++++--------- lib/main/atom/commands/commands.ts | 5 - lib/main/atom/components/statusPanel.tsx | 8 - lib/main/atomts.ts | 6 +- lib/typings/autocomplete.d.ts | 50 ++++ 14 files changed, 370 insertions(+), 219 deletions(-) delete mode 100644 keymaps/autocomplete-keymaps.cson create mode 100644 lib/typings/autocomplete.d.ts diff --git a/dist/client/client.js b/dist/client/client.js index c3dc7f994..6d5251c34 100644 --- a/dist/client/client.js +++ b/dist/client/client.js @@ -45,6 +45,9 @@ class TypescriptServiceClient { executeCompletions(args) { return this.execute("completions", args); } + executeCompletionDetails(args) { + return this.execute("completionEntryDetails", args); + } executeGetErr(args) { this.execute("geterr", args); } @@ -146,6 +149,7 @@ class TypescriptServiceClient { TypescriptServiceClient.commandWithResponse = { compileOnSaveAffectedFileList: true, compileOnSaveEmitFile: true, + completionEntryDetails: true, completions: true, occurrences: true, projectInfo: true, diff --git a/dist/main/atom/atomUtils.js b/dist/main/atom/atomUtils.js index 6ce4f987b..b550625b2 100644 --- a/dist/main/atom/atomUtils.js +++ b/dist/main/atom/atomUtils.js @@ -141,6 +141,8 @@ function kindToColor(kind) { exports.kindToColor = kindToColor; function kindToType(kind) { switch (kind) { + case 'const': + return 'constant'; case 'interface': return 'type'; case 'identifier': @@ -149,6 +151,7 @@ function kindToType(kind) { return 'function'; case 'local var': return 'variable'; + case 'let': case 'var': case 'parameter': return 'variable'; diff --git a/dist/main/atom/autoCompleteProvider.js b/dist/main/atom/autoCompleteProvider.js index 564dca154..e387e483b 100644 --- a/dist/main/atom/autoCompleteProvider.js +++ b/dist/main/atom/autoCompleteProvider.js @@ -1,56 +1,83 @@ "use strict"; const tslib_1 = require("tslib"); -const atomUtils = require("./atomUtils"); -const fs = require("fs"); -const atomts_1 = require("../atomts"); -var explicitlyTriggered = false; -function triggerAutocompletePlus() { - atom.commands.dispatch(atom.views.getView(atom.workspace.getActiveTextEditor()), 'autocomplete-plus:activate'); - explicitlyTriggered = true; -} -exports.triggerAutocompletePlus = triggerAutocompletePlus; -exports.provider = { - selector: '.source.ts, .source.tsx', - inclusionPriority: 3, - suggestionPriority: 3, - excludeLowerPriority: false, - getSuggestions: function (options) { +const atomUtils_1 = require("./atomUtils"); +const fuzzaldrin = require("fuzzaldrin"); +class AutocompleteProvider { + constructor(clientResolver) { + this.selector = ".source.ts, .source.tsx"; + this.inclusionPriority = 3; + this.suggestionPriority = 3; + this.excludeLowerPriority = false; + this.clientResolver = clientResolver; + } + getSuggestionsWithCache(prefix, location) { + return tslib_1.__awaiter(this, void 0, void 0, function* () { + if (this.lastSuggestions) { + 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) { + return this.lastSuggestions.suggestions; + } + } + const client = yield this.clientResolver.get(location.file); + const completions = yield client.executeCompletions(tslib_1.__assign({ prefix }, location)); + const suggestions = completions.body.map(entry => ({ + text: entry.name, + leftLabel: entry.kind, + type: atomUtils_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 filePath = options.editor.getPath(); - if (!filePath || !fs.existsSync(filePath)) + const location = getLocationQuery(opts); + const { prefix } = opts; + console.warn(JSON.stringify(prefix)); + if (!location.file) { return []; - const client = yield atomts_1.clientResolver.get(filePath); - if (explicitlyTriggered) { - explicitlyTriggered = false; } - else { - const prefix = options.prefix.trim(); - if (prefix === '' || prefix === ';' || prefix === '{') { - return Promise.resolve([]); - } + let suggestions = yield this.getSuggestionsWithCache(prefix, location); + const alphaPrefix = prefix.replace(/\W/g, ""); + if (alphaPrefix !== "") { + suggestions = fuzzaldrin.filter(suggestions, alphaPrefix, { key: "text" }); } - return client.executeCompletions({ - file: filePath, - prefix: options.prefix, - line: options.bufferPosition.row + 1, - offset: options.bufferPosition.column + 1 - }).then(resp => { - console.log("prefix", options.prefix); - return resp.body.map(c => { - var prefix = options.prefix; - if (c.name && c.name.startsWith('$')) { - prefix = "$" + prefix; + this.getAdditionalDetails(suggestions.slice(0, 15), location); + return suggestions; + }); + } + 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(tslib_1.__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 { - text: c.name, - replacementPrefix: prefix === "." ? "" : prefix.trim(), - rightLabel: c.name, - leftLabel: c.kind, - type: atomUtils.kindToType(c.kind), - description: null, - }; }); - }).catch(() => []); + } }); - }, -}; + } +} +exports.AutocompleteProvider = AutocompleteProvider; +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 + }; +} diff --git a/dist/main/atom/commands/commands.js b/dist/main/atom/commands/commands.js index 6fb883269..28f4ddac7 100644 --- a/dist/main/atom/commands/commands.js +++ b/dist/main/atom/commands/commands.js @@ -3,14 +3,10 @@ function __export(m) { for (var p in m) if (!exports.hasOwnProperty(p)) exports[p] = m[p]; } const atomts_1 = require("../../atomts"); -const autoCompleteProvider = require("../autoCompleteProvider"); const typeOverlayView_1 = require("../views/typeOverlayView"); const gotoHistory = require("../gotoHistory"); __export(require("../components/componentRegistry")); function registerCommands() { - atom.commands.add('atom-text-editor', 'typescript:autocomplete', (e) => { - autoCompleteProvider.triggerAutocompletePlus(); - }); atom.commands.add('atom-workspace', 'typescript:show-type', (e) => { var editor = atom.workspace.getActiveTextEditor(); var editorView = atom.views.getView(editor); diff --git a/dist/main/atom/components/statusPanel.js b/dist/main/atom/components/statusPanel.js index e11dfec66..9dc5ed189 100644 --- a/dist/main/atom/components/statusPanel.js +++ b/dist/main/atom/components/statusPanel.js @@ -27,12 +27,6 @@ class StatusPanel extends HTMLElement { this.setTsConfigPath(null); this.setBuildStatus(null); } - attachedCallback() { - console.log("attached"); - } - attributeChangedCallback() { - console.log("attrs changed", arguments); - } dispose() { this.remove(); } diff --git a/dist/main/atomts.js b/dist/main/atomts.js index 884a78f2d..9f0683cea 100644 --- a/dist/main/atomts.js +++ b/dist/main/atomts.js @@ -9,7 +9,7 @@ const error_pusher_1 = require("./error_pusher"); const typescript_editor_pane_1 = require("./typescript_editor_pane"); const statusPanel_1 = require("./atom/components/statusPanel"); const atomConfig = require("./atom/atomConfig"); -const autoCompleteProvider = require("./atom/autoCompleteProvider"); +const autoCompleteProvider_1 = require("./atom/autoCompleteProvider"); const commands = require("./atom/commands/commands"); const hyperclickProvider = require("../hyperclickProvider"); const renameView = require("./atom/views/renameView"); @@ -109,7 +109,9 @@ function consumeStatusBar(_statusBar) { } exports.consumeStatusBar = consumeStatusBar; function provide() { - return [autoCompleteProvider.provider]; + return [ + new autoCompleteProvider_1.AutocompleteProvider(exports.clientResolver), + ]; } exports.provide = provide; function getHyperclickProvider() { diff --git a/keymaps/autocomplete-keymaps.cson b/keymaps/autocomplete-keymaps.cson deleted file mode 100644 index 2000d15b2..000000000 --- a/keymaps/autocomplete-keymaps.cson +++ /dev/null @@ -1,3 +0,0 @@ -'atom-text-editor[data-grammar^="source ts"]': - 'ctrl-space': 'typescript:autocomplete' - 'cmd-space': 'typescript:autocomplete' diff --git a/lib/client/client.ts b/lib/client/client.ts index 59f4a35c5..42ca29e5f 100644 --- a/lib/client/client.ts +++ b/lib/client/client.ts @@ -39,6 +39,7 @@ export class TypescriptServiceClient { static commandWithResponse = { compileOnSaveAffectedFileList: true, compileOnSaveEmitFile: true, + completionEntryDetails: true, completions: true, occurrences: true, projectInfo: true, @@ -61,6 +62,9 @@ export class TypescriptServiceClient { executeCompletions(args: protocol.CompletionsRequestArgs): Promise { return this.execute("completions", args) } + executeCompletionDetails(args: protocol.CompletionDetailsRequestArgs): Promise { + return this.execute("completionEntryDetails", args) + } executeGetErr(args: protocol.GeterrRequestArgs) { this.execute("geterr", args) } diff --git a/lib/main/atom/atomUtils.ts b/lib/main/atom/atomUtils.ts index 812512663..76a8a6a3b 100644 --- a/lib/main/atom/atomUtils.ts +++ b/lib/main/atom/atomUtils.ts @@ -158,7 +158,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': @@ -167,6 +170,7 @@ export function kindToType(kind: string) { return 'function'; case 'local var': return 'variable'; + case 'let': case 'var': case 'parameter': return 'variable'; diff --git a/lib/main/atom/autoCompleteProvider.ts b/lib/main/atom/autoCompleteProvider.ts index d86b344d4..e8b757829 100644 --- a/lib/main/atom/autoCompleteProvider.ts +++ b/lib/main/atom/autoCompleteProvider.ts @@ -1,158 +1,239 @@ - // more: https://github.com/atom-community/autocomplete-plus/wiki/Provider-API +import {ClientResolver} from "../../client/clientResolver" +import {kindToType} from "./atomUtils" +import {Provider, RequestOptions, Suggestion} from "../../typings/autocomplete" +import {TypescriptServiceClient} from "../../client/client" +import * as fuzzaldrin from "fuzzaldrin" + +type FileLocationQuery = { + file: string + line: number + offset: number +} -import atomUtils = require('./atomUtils') -import fs = require('fs') -import {clientResolver} from "../atomts" - -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 SuggestionWithDetails = Suggestion & {details?} + +export class AutocompleteProvider implements Provider { + selector = ".source.ts, .source.tsx" + inclusionPriority = 3 + suggestionPriority = 3 + excludeLowerPriority = false + + private clientResolver: ClientResolver + private lastSuggestions: { + // Client used to get the suggestions + client: TypescriptServiceClient + + // File and position for the suggestions + location: FileLocationQuery + + // Prefix used + prefix: string + + // The completions that were returned for the position + suggestions: SuggestionWithDetails[] + } + + constructor(clientResolver: ClientResolver) { + this.clientResolver = clientResolver + } + + // Try to reuse the last completions we got from tsserver if they're for the same position. + async getSuggestionsWithCache( + prefix: string, + location: FileLocationQuery + ): Promise { + if (this.lastSuggestions) { + 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) { + return this.lastSuggestions.suggestions + } } - /** The suggestion */ - export interface Suggestion { - //Either text or snippet is required + 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, + } - text?: string; - snippet?: string; + return suggestions + } - replacementPrefix?: string; + async getSuggestions(opts: RequestOptions): Promise { + const location = getLocationQuery(opts) + const {prefix} = opts - rightLabel?: string; - rightLabelHTML?: string; - leftLabel?: string; - type: string; - description?: string; + console.warn(JSON.stringify(prefix)) + + if (!location.file) { + return [] } - /** 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; + let suggestions = await this.getSuggestionsWithCache(prefix, location) + + const alphaPrefix = prefix.replace(/\W/g, "") + if (alphaPrefix !== "") { + suggestions = fuzzaldrin.filter(suggestions, alphaPrefix, {key: "text"}) } -} -var explicitlyTriggered = false; -export function triggerAutocompletePlus() { - atom.commands.dispatch( - atom.views.getView(atom.workspace.getActiveTextEditor()), - 'autocomplete-plus:activate'); - explicitlyTriggered = true; -} + // Get additional details for the first few suggestions, but don't wait for it to complete + this.getAdditionalDetails(suggestions.slice(0, 15), location) -export var provider: autocompleteplus.Provider = { - selector: '.source.ts, .source.tsx', - inclusionPriority: 3, - suggestionPriority: 3, - excludeLowerPriority: false, - getSuggestions: async function (options: autocompleteplus.RequestOptions): Promise { - - const filePath = options.editor.getPath() - - // We refuse to work on files that are not on disk. - if (!filePath || !fs.existsSync(filePath)) - return []; - - const client = await clientResolver.get(filePath) - - // var {isReference, isRequire, isImport} = getModuleAutocompleteType(options.scopeDescriptor.scopes) - // - // // For file path completions - // if (isReference || isRequire || isImport) { - // return parent.getRelativePathsInProject({ filePath, prefix: options.prefix, includeExternalModules: isReference }) - // .then((resp) => { - // - // var range = options.editor.bufferRangeForScopeAtCursor(".string.quoted") - // var cursor = options.editor.getCursorBufferPosition() - // - // // 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 [] - // } - // - // var content = options.editor.getTextInBufferRange(range).replace(/^['"]|['"]$/g, "") - // - // return resp.files.map(file => { - // var relativePath = file.relativePath; - // - // /** Optionally customize this in future */ - // var suggestionText = relativePath; - // - // var suggestion: autocompleteplus.Suggestion = { - // text: suggestionText, - // replacementPrefix: content, - // rightLabelHTML: '' + file.name + '', - // type: 'import' - // }; - // - // 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() + return suggestions + } + + 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] - if (prefix === '' || prefix === ';' || prefix === '{') { - return Promise.resolve([]); - } + suggestion.details = detail + suggestion.rightLabel = detail.displayParts.map(d => d.text).join("") + + if (detail.documentation) { + suggestion.description = detail.documentation.map(d => d.text).join(" ") } + }) + } + } +} + +// 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 +} - return client.executeCompletions({ - file: filePath, - prefix: options.prefix, - line: options.bufferPosition.row+1, - offset: options.bufferPosition.column+1 - }).then(resp => { - console.log("prefix", options.prefix) - return resp.body.map(c => { - - // 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: prefix === "." ? "" : prefix.trim(), - rightLabel: c.name, - leftLabel: c.kind, - type: atomUtils.kindToType(c.kind), - description: null, - }; - // } - }); - }).catch(() => []) - }, +function getLocationQuery(opts: RequestOptions): FileLocationQuery { + return { + file: opts.editor.getPath(), + line: opts.bufferPosition.row+1, + offset: opts.bufferPosition.column+1 + } } + +// export var provider: autocompleteplus.Provider = { +// selector: '.source.ts, .source.tsx', +// inclusionPriority: 3, +// suggestionPriority: 3, +// excludeLowerPriority: false, +// getSuggestions: async function (options: autocompleteplus.RequestOptions): Promise { +// +// const filePath = options.editor.getPath() +// +// // We refuse to work on files that are not on disk. +// if (!filePath || !fs.existsSync(filePath)) +// return []; +// +// const client = await clientResolver.get(filePath) +// +// // var {isReference, isRequire, isImport} = getModuleAutocompleteType(options.scopeDescriptor.scopes) +// // +// // // For file path completions +// // if (isReference || isRequire || isImport) { +// // return parent.getRelativePathsInProject({ filePath, prefix: options.prefix, includeExternalModules: isReference }) +// // .then((resp) => { +// // +// // var range = options.editor.bufferRangeForScopeAtCursor(".string.quoted") +// // var cursor = options.editor.getCursorBufferPosition() +// // +// // // 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 [] +// // } +// // +// // var content = options.editor.getTextInBufferRange(range).replace(/^['"]|['"]$/g, "") +// // +// // return resp.files.map(file => { +// // var relativePath = file.relativePath; +// // +// // /** Optionally customize this in future */ +// // var suggestionText = relativePath; +// // +// // var suggestion: autocompleteplus.Suggestion = { +// // text: suggestionText, +// // replacementPrefix: content, +// // rightLabelHTML: '' + file.name + '', +// // type: 'import' +// // }; +// // +// // 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([]); +// } +// } +// +// return client.executeCompletions({ +// file: filePath, +// prefix: options.prefix, +// line: options.bufferPosition.row+1, +// offset: options.bufferPosition.column+1 +// }).then(resp => { +// console.log("prefix", options.prefix) +// return resp.body.map(c => { +// +// // 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: prefix === "." ? "" : prefix.trim(), +// rightLabel: c.name, +// leftLabel: c.kind, +// type: atomUtils.kindToType(c.kind), +// description: null, +// }; +// // } +// }); +// }).catch(() => []) +// }, +// } diff --git a/lib/main/atom/commands/commands.ts b/lib/main/atom/commands/commands.ts index 0ceb8d8b7..a55bfad94 100644 --- a/lib/main/atom/commands/commands.ts +++ b/lib/main/atom/commands/commands.ts @@ -1,6 +1,5 @@ import {clientResolver} from "../../atomts" // import atomUtils = require("../atomUtils"); -import autoCompleteProvider = require("../autoCompleteProvider"); // import path = require('path'); // import renameView = require("../views/renameView"); // import fileSymbolsView = require("../views/fileSymbolsView"); @@ -97,10 +96,6 @@ export function registerCommands() { // }); // }); - atom.commands.add('atom-text-editor', 'typescript:autocomplete', (e) => { - autoCompleteProvider.triggerAutocompletePlus(); - }); - // atom.commands.add('atom-text-editor', 'typescript:rename-refactor', (e) => { // // Rename variable // if (true) { diff --git a/lib/main/atom/components/statusPanel.tsx b/lib/main/atom/components/statusPanel.tsx index 8e8a9dce7..3696407ad 100644 --- a/lib/main/atom/components/statusPanel.tsx +++ b/lib/main/atom/components/statusPanel.tsx @@ -58,14 +58,6 @@ export class StatusPanel extends HTMLElement { this.setBuildStatus(null) } - attachedCallback() { - console.log("attached") - } - - attributeChangedCallback() { - console.log("attrs changed", arguments) - } - dispose() { this.remove() } diff --git a/lib/main/atomts.ts b/lib/main/atomts.ts index f2a93a0fa..e923e1488 100644 --- a/lib/main/atomts.ts +++ b/lib/main/atomts.ts @@ -15,7 +15,7 @@ import {TypescriptEditorPane} from "./typescript_editor_pane" import {StatusPanel} from "./atom/components/statusPanel" import * as atomConfig from './atom/atomConfig' // import * as atomUtils from './atom/atomUtils' -import * as autoCompleteProvider from './atom/autoCompleteProvider' +import {AutocompleteProvider} from './atom/autoCompleteProvider' import * as commands from "./atom/commands/commands" // import * as fs from 'fs' import * as hyperclickProvider from "../hyperclickProvider" @@ -150,7 +150,9 @@ export function consumeStatusBar(_statusBar) { // Registering an autocomplete provider export function provide() { - return [autoCompleteProvider.provider]; + return [ + new AutocompleteProvider(clientResolver), + ] } export function getHyperclickProvider() { 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 +} From efc183cfd92891e1bc7546f3401def18e16fefcd Mon Sep 17 00:00:00 2001 From: Guntars Asmanis-Graham Date: Mon, 19 Dec 2016 11:39:42 -0500 Subject: [PATCH 29/70] Tweak the highlighting a little --- dist/main/typescript_editor_pane.js | 17 ++++++++++++----- lib/main/typescript_editor_pane.ts | 24 ++++++++++++++++++------ 2 files changed, 30 insertions(+), 11 deletions(-) diff --git a/dist/main/typescript_editor_pane.js b/dist/main/typescript_editor_pane.js index 37c9f5024..732e52a19 100644 --- a/dist/main/typescript_editor_pane.js +++ b/dist/main/typescript_editor_pane.js @@ -34,6 +34,7 @@ class TypescriptEditorPane { this.isActive = false; }; this.onDidChange = diff => { + this.changedAt = Date.now(); if (this.isOpen) { this.opts.statusPanel.setBuildStatus(null); this.client.executeChange({ @@ -46,12 +47,12 @@ class TypescriptEditorPane { }); } }; - this.onDidChangeCursorPosition = () => { + this.onDidChangeCursorPosition = lodash_1.debounce(() => { if (!this.isTypescript) { return; } - for (const marker of this.occurrenceMarkers) { - marker.destroy(); + if ((Date.now() - this.changedAt) < 100) { + return; } const pos = this.editor.getLastCursor().getBufferPosition(); this.client.executeOccurances({ @@ -59,6 +60,7 @@ class TypescriptEditorPane { line: pos.row + 1, offset: pos.column + 1 }).then(result => { + this.clearOccurrenceMarkers(); for (const ref of result.body) { const marker = this.editor.markBufferRange(tsUtil_1.spanToRange(ref)); this.editor.decorateMarker(marker, { @@ -67,8 +69,8 @@ class TypescriptEditorPane { }); this.occurrenceMarkers.push(marker); } - }).catch(() => null); - }; + }).catch(() => this.clearOccurrenceMarkers()); + }, 100); this.onDidDestroy = () => { this.dispose(); }; @@ -169,6 +171,11 @@ class TypescriptEditorPane { } this.opts.onDispose(this); } + clearOccurrenceMarkers() { + for (const marker of this.occurrenceMarkers) { + marker.destroy(); + } + } setupTooltipView() { const editorView = atom_space_pen_views_1.$(atom.views.getView(this.editor)); tooltipManager.attach(editorView, this.editor); diff --git a/lib/main/typescript_editor_pane.ts b/lib/main/typescript_editor_pane.ts index 761975fa8..b9e32d4f8 100644 --- a/lib/main/typescript_editor_pane.ts +++ b/lib/main/typescript_editor_pane.ts @@ -2,7 +2,7 @@ import {$} from "atom-space-pen-views" import {basename} from "path" import {clientResolver} from "./atomts" import {CompositeDisposable} from "atom" -import {flatten} from "lodash" +import {debounce, flatten} from "lodash" import {spanToRange} from "./utils/tsUtil" import {TypescriptServiceClient} from "../client/client" import {StatusPanel} from "./atom/components/statusPanel" @@ -22,6 +22,7 @@ interface PaneOptions { } export class TypescriptEditorPane implements AtomCore.Disposable { + changedAt: number activeAt: number client: TypescriptServiceClient configFile: string = "" @@ -131,6 +132,8 @@ export class TypescriptEditorPane implements AtomCore.Disposable { } onDidChange: onChangeObserver = diff => { + this.changedAt = Date.now() + if (this.isOpen) { this.opts.statusPanel.setBuildStatus(null) @@ -145,13 +148,20 @@ export class TypescriptEditorPane implements AtomCore.Disposable { } } - onDidChangeCursorPosition = () => { + clearOccurrenceMarkers() { + for (const marker of this.occurrenceMarkers) { + marker.destroy() + } + } + + onDidChangeCursorPosition = debounce(() => { if (!this.isTypescript) { return } - for (const marker of this.occurrenceMarkers) { - marker.destroy() + // Don't update the highlights if the cursor is moving because of the changes to the buffer + if ((Date.now() - this.changedAt) < 100) { + return } const pos = this.editor.getLastCursor().getBufferPosition() @@ -161,6 +171,8 @@ export class TypescriptEditorPane implements AtomCore.Disposable { 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, { @@ -169,8 +181,8 @@ export class TypescriptEditorPane implements AtomCore.Disposable { }) this.occurrenceMarkers.push(marker) } - }).catch(() => null) - } + }).catch(() => this.clearOccurrenceMarkers()) + }, 100) onDidDestroy = () => { this.dispose() From ce6c5f2d23199e19bc3e9f9493f09e1584f42150 Mon Sep 17 00:00:00 2001 From: Guntars Asmanis-Graham Date: Mon, 19 Dec 2016 12:09:21 -0500 Subject: [PATCH 30/70] Remove unused react typings --- lib/tsconfig.json | 2 +- package.json | 1 - 2 files changed, 1 insertion(+), 2 deletions(-) diff --git a/lib/tsconfig.json b/lib/tsconfig.json index 75464d184..b6cad2614 100644 --- a/lib/tsconfig.json +++ b/lib/tsconfig.json @@ -13,7 +13,7 @@ "outDir": "../dist", "sourceMap": false, "jsx": "react", - "types": ["react"], + "types": [], "reactNamespace": "dom" }, "atom": { diff --git a/package.json b/package.json index f2dbe2bbd..aa2718267 100644 --- a/package.json +++ b/package.json @@ -52,7 +52,6 @@ "@types/atom": "0.0.35", "@types/byline": "^4.2.31", "@types/lodash": "4.14.41", - "@types/react": "0.14.52", "@types/resolve": "0.0.4", "atom-package-deps": "^2.0.3", "atom-space-pen-views": "^2.0.4", From 79fd8ba5d1db8f5fa50ba6ac03adc1eddb4f1f8c Mon Sep 17 00:00:00 2001 From: Guntars Asmanis-Graham Date: Wed, 21 Dec 2016 22:05:25 -0500 Subject: [PATCH 31/70] Fix minor things with the autocomplete provider --- dist/main/atom/autoCompleteProvider.js | 22 +++- lib/main/atom/autoCompleteProvider.ts | 141 ++++--------------------- 2 files changed, 42 insertions(+), 121 deletions(-) diff --git a/dist/main/atom/autoCompleteProvider.js b/dist/main/atom/autoCompleteProvider.js index e387e483b..f25cc903f 100644 --- a/dist/main/atom/autoCompleteProvider.js +++ b/dist/main/atom/autoCompleteProvider.js @@ -5,6 +5,7 @@ const fuzzaldrin = require("fuzzaldrin"); class AutocompleteProvider { constructor(clientResolver) { this.selector = ".source.ts, .source.tsx"; + this.disableForSelector = ".comment.block.documentation.ts, .comment.block.documentation.tsx"; this.inclusionPriority = 3; this.suggestionPriority = 3; this.excludeLowerPriority = false; @@ -40,17 +41,21 @@ class AutocompleteProvider { return tslib_1.__awaiter(this, void 0, void 0, function* () { const location = getLocationQuery(opts); const { prefix } = opts; - console.warn(JSON.stringify(prefix)); if (!location.file) { return []; } - let suggestions = yield this.getSuggestionsWithCache(prefix, location); + try { + var suggestions = yield this.getSuggestionsWithCache(prefix, location); + } + catch (error) { + return []; + } const alphaPrefix = prefix.replace(/\W/g, ""); if (alphaPrefix !== "") { suggestions = fuzzaldrin.filter(suggestions, alphaPrefix, { key: "text" }); } this.getAdditionalDetails(suggestions.slice(0, 15), location); - return suggestions; + return suggestions.map(suggestion => (tslib_1.__assign({ replacementPrefix: getReplacementPrefix(prefix, suggestion.text) }, suggestion))); }); } getAdditionalDetails(suggestions, location) { @@ -70,6 +75,17 @@ class AutocompleteProvider { } } exports.AutocompleteProvider = AutocompleteProvider; +function getReplacementPrefix(prefix, replacement) { + if (prefix === ".") { + return ""; + } + else if (replacement.startsWith("$")) { + return "$" + prefix; + } + else { + return prefix; + } +} function getNormalizedCol(prefix, col) { const length = prefix === "." ? 0 : prefix.length; return col - length; diff --git a/lib/main/atom/autoCompleteProvider.ts b/lib/main/atom/autoCompleteProvider.ts index e8b757829..7fc48d700 100644 --- a/lib/main/atom/autoCompleteProvider.ts +++ b/lib/main/atom/autoCompleteProvider.ts @@ -1,20 +1,16 @@ // more: https://github.com/atom-community/autocomplete-plus/wiki/Provider-API import {ClientResolver} from "../../client/clientResolver" -import {kindToType} from "./atomUtils" +import {kindToType, FileLocationQuery} from "./atomUtils" import {Provider, RequestOptions, Suggestion} from "../../typings/autocomplete" import {TypescriptServiceClient} from "../../client/client" import * as fuzzaldrin from "fuzzaldrin" -type FileLocationQuery = { - file: string - line: number - offset: number -} - type SuggestionWithDetails = Suggestion & {details?} export class AutocompleteProvider implements Provider { selector = ".source.ts, .source.tsx" + disableForSelector = ".comment.block.documentation.ts, .comment.block.documentation.tsx" + inclusionPriority = 3 suggestionPriority = 3 excludeLowerPriority = false @@ -76,13 +72,15 @@ export class AutocompleteProvider implements Provider { const location = getLocationQuery(opts) const {prefix} = opts - console.warn(JSON.stringify(prefix)) - if (!location.file) { return [] } - let suggestions = await this.getSuggestionsWithCache(prefix, location) + try { + var suggestions = await this.getSuggestionsWithCache(prefix, location) + } catch (error) { + return [] + } const alphaPrefix = prefix.replace(/\W/g, "") if (alphaPrefix !== "") { @@ -92,7 +90,10 @@ export class AutocompleteProvider implements Provider { // Get additional details for the first few suggestions, but don't wait for it to complete this.getAdditionalDetails(suggestions.slice(0, 15), location) - return suggestions + return suggestions.map(suggestion => ({ + replacementPrefix: getReplacementPrefix(prefix, suggestion.text), + ...suggestion + })) } async getAdditionalDetails(suggestions: SuggestionWithDetails[], location: FileLocationQuery) { @@ -116,6 +117,17 @@ export class AutocompleteProvider implements Provider { } } +// If prefix is ".", don't replace anything, just insert the completion, replace it otherwise. +function getReplacementPrefix(prefix: string, replacement: string): string { + if (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 { @@ -130,110 +142,3 @@ function getLocationQuery(opts: RequestOptions): FileLocationQuery { offset: opts.bufferPosition.column+1 } } - -// export var provider: autocompleteplus.Provider = { -// selector: '.source.ts, .source.tsx', -// inclusionPriority: 3, -// suggestionPriority: 3, -// excludeLowerPriority: false, -// getSuggestions: async function (options: autocompleteplus.RequestOptions): Promise { -// -// const filePath = options.editor.getPath() -// -// // We refuse to work on files that are not on disk. -// if (!filePath || !fs.existsSync(filePath)) -// return []; -// -// const client = await clientResolver.get(filePath) -// -// // var {isReference, isRequire, isImport} = getModuleAutocompleteType(options.scopeDescriptor.scopes) -// // -// // // For file path completions -// // if (isReference || isRequire || isImport) { -// // return parent.getRelativePathsInProject({ filePath, prefix: options.prefix, includeExternalModules: isReference }) -// // .then((resp) => { -// // -// // var range = options.editor.bufferRangeForScopeAtCursor(".string.quoted") -// // var cursor = options.editor.getCursorBufferPosition() -// // -// // // 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 [] -// // } -// // -// // var content = options.editor.getTextInBufferRange(range).replace(/^['"]|['"]$/g, "") -// // -// // return resp.files.map(file => { -// // var relativePath = file.relativePath; -// // -// // /** Optionally customize this in future */ -// // var suggestionText = relativePath; -// // -// // var suggestion: autocompleteplus.Suggestion = { -// // text: suggestionText, -// // replacementPrefix: content, -// // rightLabelHTML: '' + file.name + '', -// // type: 'import' -// // }; -// // -// // 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([]); -// } -// } -// -// return client.executeCompletions({ -// file: filePath, -// prefix: options.prefix, -// line: options.bufferPosition.row+1, -// offset: options.bufferPosition.column+1 -// }).then(resp => { -// console.log("prefix", options.prefix) -// return resp.body.map(c => { -// -// // 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: prefix === "." ? "" : prefix.trim(), -// rightLabel: c.name, -// leftLabel: c.kind, -// type: atomUtils.kindToType(c.kind), -// description: null, -// }; -// // } -// }); -// }).catch(() => []) -// }, -// } From 616d6c3f71a942fd1a370bc76428450b810aaf93 Mon Sep 17 00:00:00 2001 From: Guntars Asmanis-Graham Date: Wed, 21 Dec 2016 22:17:40 -0500 Subject: [PATCH 32/70] =?UTF-8?q?Don=E2=80=99t=20trigger=20occurrences=20w?= =?UTF-8?q?hen=20editing?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- dist/main/atom/autoCompleteProvider.js | 2 +- dist/main/typescript_editor_pane.js | 18 +++++++++++------- lib/main/atom/autoCompleteProvider.ts | 2 +- lib/main/typescript_editor_pane.ts | 24 ++++++++++++++---------- 4 files changed, 27 insertions(+), 19 deletions(-) diff --git a/dist/main/atom/autoCompleteProvider.js b/dist/main/atom/autoCompleteProvider.js index f25cc903f..7dfaaee6c 100644 --- a/dist/main/atom/autoCompleteProvider.js +++ b/dist/main/atom/autoCompleteProvider.js @@ -5,7 +5,7 @@ const fuzzaldrin = require("fuzzaldrin"); class AutocompleteProvider { constructor(clientResolver) { this.selector = ".source.ts, .source.tsx"; - this.disableForSelector = ".comment.block.documentation.ts, .comment.block.documentation.tsx"; + this.disableForSelector = ".comment.block.documentation.ts, .comment.block.documentation.tsx, .comment.line.double-slash.ts, .comment.line.double-slash.tsx"; this.inclusionPriority = 3; this.suggestionPriority = 3; this.excludeLowerPriority = false; diff --git a/dist/main/typescript_editor_pane.js b/dist/main/typescript_editor_pane.js index 732e52a19..3fbb4e770 100644 --- a/dist/main/typescript_editor_pane.js +++ b/dist/main/typescript_editor_pane.js @@ -47,13 +47,7 @@ class TypescriptEditorPane { }); } }; - this.onDidChangeCursorPosition = lodash_1.debounce(() => { - if (!this.isTypescript) { - return; - } - if ((Date.now() - this.changedAt) < 100) { - return; - } + this.updateMarkers = lodash_1.debounce(() => { const pos = this.editor.getLastCursor().getBufferPosition(); this.client.executeOccurances({ file: this.filePath, @@ -71,6 +65,16 @@ class TypescriptEditorPane { } }).catch(() => this.clearOccurrenceMarkers()); }, 100); + this.onDidChangeCursorPosition = ({ textChanged }) => { + if (!this.isTypescript) { + return; + } + if (textChanged) { + this.clearOccurrenceMarkers(); + return; + } + this.updateMarkers(); + }; this.onDidDestroy = () => { this.dispose(); }; diff --git a/lib/main/atom/autoCompleteProvider.ts b/lib/main/atom/autoCompleteProvider.ts index 7fc48d700..45d6329e9 100644 --- a/lib/main/atom/autoCompleteProvider.ts +++ b/lib/main/atom/autoCompleteProvider.ts @@ -9,7 +9,7 @@ type SuggestionWithDetails = Suggestion & {details?} export class AutocompleteProvider implements Provider { selector = ".source.ts, .source.tsx" - disableForSelector = ".comment.block.documentation.ts, .comment.block.documentation.tsx" + disableForSelector = ".comment.block.documentation.ts, .comment.block.documentation.tsx, .comment.line.double-slash.ts, .comment.line.double-slash.tsx" inclusionPriority = 3 suggestionPriority = 3 diff --git a/lib/main/typescript_editor_pane.ts b/lib/main/typescript_editor_pane.ts index b9e32d4f8..be47ca7bb 100644 --- a/lib/main/typescript_editor_pane.ts +++ b/lib/main/typescript_editor_pane.ts @@ -154,16 +154,7 @@ export class TypescriptEditorPane implements AtomCore.Disposable { } } - onDidChangeCursorPosition = debounce(() => { - if (!this.isTypescript) { - return - } - - // Don't update the highlights if the cursor is moving because of the changes to the buffer - if ((Date.now() - this.changedAt) < 100) { - return - } - + updateMarkers = debounce(() => { const pos = this.editor.getLastCursor().getBufferPosition() this.client.executeOccurances({ @@ -184,6 +175,19 @@ export class TypescriptEditorPane implements AtomCore.Disposable { }).catch(() => this.clearOccurrenceMarkers()) }, 100) + onDidChangeCursorPosition = ({textChanged}) => { + if (!this.isTypescript) { + return + } + + if (textChanged) { + this.clearOccurrenceMarkers() + return + } + + this.updateMarkers() + } + onDidDestroy = () => { this.dispose() } From e5ab667e3bfd2a2f4fa5cdf58d7a8dc18afa375e Mon Sep 17 00:00:00 2001 From: Guntars Asmanis-Graham Date: Wed, 21 Dec 2016 23:29:18 -0500 Subject: [PATCH 33/70] Use onDidStopChanging for change notifications --- lib/main/atom/atomUtils.ts | 33 ++++++++++++--------- lib/main/atom/components/statusPanel.tsx | 4 +-- lib/main/typescript_editor_pane.ts | 37 +++++++++++------------- 3 files changed, 39 insertions(+), 35 deletions(-) diff --git a/lib/main/atom/atomUtils.ts b/lib/main/atom/atomUtils.ts index 76a8a6a3b..7c6793280 100644 --- a/lib/main/atom/atomUtils.ts +++ b/lib/main/atom/atomUtils.ts @@ -4,16 +4,22 @@ import * as fsu from "../utils/fsUtil"; import _atom = require('atom'); 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); +export interface LocationQuery { + line: number + offset: number } -// 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 interface FileLocationQuery extends LocationQuery { + file: string +} + +// 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 + } } export function isAllowedExtension(ext: string) { @@ -60,11 +66,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; } { diff --git a/lib/main/atom/components/statusPanel.tsx b/lib/main/atom/components/statusPanel.tsx index 3696407ad..f45d40cc2 100644 --- a/lib/main/atom/components/statusPanel.tsx +++ b/lib/main/atom/components/statusPanel.tsx @@ -134,11 +134,11 @@ export class StatusPanel extends HTMLElement { } show() { - this.style.display = "block" + this.classList.remove("hide") } hide() { - this.style.display = "none" + this.classList.add("hide") } static create() { diff --git a/lib/main/typescript_editor_pane.ts b/lib/main/typescript_editor_pane.ts index be47ca7bb..1db1b67a3 100644 --- a/lib/main/typescript_editor_pane.ts +++ b/lib/main/typescript_editor_pane.ts @@ -110,7 +110,7 @@ export class TypescriptEditorPane implements AtomCore.Disposable { this.isActive = true if (this.isTypescript && this.filePath) { - // this.mainPanel.show() + this.opts.statusPanel.show() if (this.client) { // The first activation might happen before we even have a client @@ -128,24 +128,11 @@ export class TypescriptEditorPane implements AtomCore.Disposable { onDeactivated = () => { this.isActive = false - // this.mainPanel.hide() + this.opts.statusPanel.hide() } onDidChange: onChangeObserver = diff => { this.changedAt = Date.now() - - if (this.isOpen) { - this.opts.statusPanel.setBuildStatus(null) - - this.client.executeChange({ - endLine: diff.oldRange.end.row+1, - endOffset: diff.oldRange.end.column+1, - file: this.editor.getPath(), - line: diff.oldRange.start.row+1, - offset: diff.oldRange.start.column+1, - insertString: diff.newText, - }) - } } clearOccurrenceMarkers() { @@ -193,9 +180,6 @@ export class TypescriptEditorPane implements AtomCore.Disposable { } onDidSave = async event => { - // Observe editors saving - console.log("saved", this.filePath) - if (this.filePath !== event.path) { console.log("file path changed to", event.path) this.client = await clientResolver.get(event.path) @@ -241,9 +225,22 @@ export class TypescriptEditorPane implements AtomCore.Disposable { } } - onDidStopChanging = () => { - console.log("did stop changing", this.filePath) + onDidStopChanging = ({changes}) => { if (this.isTypescript && this.filePath) { + if (this.isOpen) { + this.opts.statusPanel.setBuildStatus(null) + for (const change of changes) { + this.client.executeChange({ + endLine: change.start.row + change.oldExtent.row + 1, + endOffset: change.start.column + change.oldExtent.column + 1, + file: this.filePath, + line: change.start.row + 1, + offset: change.start.column + 1, + insertString: change.newText, + }) + } + } + this.client.executeGetErr({ files: [this.filePath], delay: 100 From 84b1fba06bd3c2ef844e99533295b7085b0927ad Mon Sep 17 00:00:00 2001 From: Guntars Asmanis-Graham Date: Wed, 21 Dec 2016 23:55:04 -0500 Subject: [PATCH 34/70] Restore goToDefinition command --- dist/client/client.js | 4 + dist/main/atom/atomUtils.js | 19 ++- dist/main/atom/commands/commands.js | 53 +------ dist/main/atom/commands/goToDeclaration.js | 37 +++++ dist/main/atom/commands/registry.js | 2 + dist/main/atom/components/statusPanel.js | 4 +- dist/main/atomts.js | 2 +- dist/main/typescript_editor_pane.js | 31 +++-- lib/client/client.ts | 4 + lib/main/atom/commands/commands.ts | 152 ++++++++------------- lib/main/atom/commands/goToDeclaration.ts | 38 ++++++ lib/main/atom/commands/registry.ts | 14 ++ lib/main/atomts.ts | 2 +- lib/main/typescript_editor_pane.ts | 1 - 14 files changed, 191 insertions(+), 172 deletions(-) create mode 100644 dist/main/atom/commands/goToDeclaration.js create mode 100644 dist/main/atom/commands/registry.js create mode 100644 lib/main/atom/commands/goToDeclaration.ts create mode 100644 lib/main/atom/commands/registry.ts diff --git a/dist/client/client.js b/dist/client/client.js index 6d5251c34..b11004ac0 100644 --- a/dist/client/client.js +++ b/dist/client/client.js @@ -48,6 +48,9 @@ class TypescriptServiceClient { executeCompletionDetails(args) { return this.execute("completionEntryDetails", args); } + executeDefinition(args) { + return this.execute("definition", args); + } executeGetErr(args) { this.execute("geterr", args); } @@ -151,6 +154,7 @@ TypescriptServiceClient.commandWithResponse = { compileOnSaveEmitFile: true, completionEntryDetails: true, completions: true, + definition: true, occurrences: true, projectInfo: true, quickinfo: true, diff --git a/dist/main/atom/atomUtils.js b/dist/main/atom/atomUtils.js index b550625b2..5fa3bb6a9 100644 --- a/dist/main/atom/atomUtils.js +++ b/dist/main/atom/atomUtils.js @@ -1,19 +1,18 @@ "use strict"; +const tslib_1 = require("tslib"); const path = require("path"); const fs = require("fs"); const fsu = require("../utils/fsUtil"); const _atom = require("atom"); const url = require("url"); 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); -} -exports.getEditorPositionForBufferPosition = getEditorPositionForBufferPosition; function isAllowedExtension(ext) { return (ext == '.ts' || ext == '.tst' || ext == '.tsx'); } @@ -59,10 +58,8 @@ function onDiskAndTsRelated(editor) { } exports.onDiskAndTsRelated = onDiskAndTsRelated; function getFilePathPosition() { - var editor = atom.workspace.getActiveTextEditor(); - var filePath = editor.getPath(); - var position = getEditorPosition(editor); - return { filePath, position }; + const editor = atom.workspace.getActiveTextEditor(); + return tslib_1.__assign({ file: editor.getPath() }, getEditorPosition(editor)); } exports.getFilePathPosition = getFilePathPosition; function getFilePath() { diff --git a/dist/main/atom/commands/commands.js b/dist/main/atom/commands/commands.js index 28f4ddac7..0ac05a49f 100644 --- a/dist/main/atom/commands/commands.js +++ b/dist/main/atom/commands/commands.js @@ -1,51 +1,10 @@ "use strict"; -function __export(m) { - for (var p in m) if (!exports.hasOwnProperty(p)) exports[p] = m[p]; -} -const atomts_1 = require("../../atomts"); -const typeOverlayView_1 = require("../views/typeOverlayView"); -const gotoHistory = require("../gotoHistory"); -__export(require("../components/componentRegistry")); -function registerCommands() { - 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 = cursor.getBufferPosition(); - var filePath = editor.getPath(); - atomts_1.clientResolver.get(filePath).then(client => { - return client.executeQuickInfo({ - file: filePath, - line: position.row + 1, - offset: position.column + 1 - }).then(({ body: { displayString, documentation } }) => { - var decoration = editor.decorateMarker(cursor.getMarker(), { - type: 'overlay', - item: typeOverlayView_1.create(displayString, documentation) - }); - var onKeydown = (e) => { - if (e.keyCode == 27) { - 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); - }).catch(() => { }); - }); - }); - atom.commands.add('atom-workspace', 'typescript:go-to-next', (e) => { - gotoHistory.gotoNext(); - }); - atom.commands.add('atom-workspace', 'typescript:go-to-previous', (e) => { - gotoHistory.gotoPrevious(); - }); +const registry_1 = require("./registry"); +require("./goToDeclaration"); +function registerCommands(deps) { + for (const [name, command] of registry_1.commands) { + atom.commands.add("atom-workspace", name, command(deps)); + } atom.commands.add('atom-workspace', 'typescript:sync', (e) => { console.log("typescript:sync trigerred"); }); diff --git a/dist/main/atom/commands/goToDeclaration.js b/dist/main/atom/commands/goToDeclaration.js new file mode 100644 index 000000000..7cdc20206 --- /dev/null +++ b/dist/main/atom/commands/goToDeclaration.js @@ -0,0 +1,37 @@ +"use strict"; +const tslib_1 = require("tslib"); +const registry_1 = require("./registry"); +const atomUtils_1 = require("../atomUtils"); +const simpleSelectionView_1 = require("../views/simpleSelectionView"); +registry_1.commands.set("typescript:go-to-declaration", deps => { + return (e) => tslib_1.__awaiter(this, void 0, void 0, function* () { + if (!atomUtils_1.commandForTypeScript(e)) { + return; + } + const location = atomUtils_1.getFilePathPosition(); + const client = yield deps.clientResolver.get(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: open + }); + } + else { + open(result.body[0]); + } + function open(item) { + atom.workspace.open(item.file, { + initialLine: item.start.line - 1, + initialColumn: item.start.offset - 1 + }); + } + }); +}); diff --git a/dist/main/atom/commands/registry.js b/dist/main/atom/commands/registry.js new file mode 100644 index 000000000..0ba219db8 --- /dev/null +++ b/dist/main/atom/commands/registry.js @@ -0,0 +1,2 @@ +"use strict"; +exports.commands = new Map(); diff --git a/dist/main/atom/components/statusPanel.js b/dist/main/atom/components/statusPanel.js index 9dc5ed189..7c7adfa02 100644 --- a/dist/main/atom/components/statusPanel.js +++ b/dist/main/atom/components/statusPanel.js @@ -98,10 +98,10 @@ class StatusPanel extends HTMLElement { } } show() { - this.style.display = "block"; + this.classList.remove("hide"); } hide() { - this.style.display = "none"; + this.classList.add("hide"); } static create() { return document.createElement("ts-status-panel"); diff --git a/dist/main/atomts.js b/dist/main/atomts.js index 9f0683cea..03cfeba6b 100644 --- a/dist/main/atomts.js +++ b/dist/main/atomts.js @@ -46,7 +46,7 @@ function activate(state) { }); } renameView.attach(); - commands.registerCommands(); + commands.registerCommands({ clientResolver: exports.clientResolver }); const panes = []; const onSave = lodash_1.debounce((pane) => { console.log("checking errors for all panes for", pane.filePath); diff --git a/dist/main/typescript_editor_pane.js b/dist/main/typescript_editor_pane.js index 3fbb4e770..52b80aa8b 100644 --- a/dist/main/typescript_editor_pane.js +++ b/dist/main/typescript_editor_pane.js @@ -20,6 +20,7 @@ class TypescriptEditorPane { this.activeAt = Date.now(); this.isActive = true; if (this.isTypescript && this.filePath) { + this.opts.statusPanel.show(); if (this.client) { this.client.executeGetErr({ files: [this.filePath], @@ -32,20 +33,10 @@ class TypescriptEditorPane { }; this.onDeactivated = () => { this.isActive = false; + this.opts.statusPanel.hide(); }; this.onDidChange = diff => { this.changedAt = Date.now(); - if (this.isOpen) { - this.opts.statusPanel.setBuildStatus(null); - this.client.executeChange({ - endLine: diff.oldRange.end.row + 1, - endOffset: diff.oldRange.end.column + 1, - file: this.editor.getPath(), - line: diff.oldRange.start.row + 1, - offset: diff.oldRange.start.column + 1, - insertString: diff.newText, - }); - } }; this.updateMarkers = lodash_1.debounce(() => { const pos = this.editor.getLastCursor().getBufferPosition(); @@ -79,7 +70,6 @@ class TypescriptEditorPane { this.dispose(); }; this.onDidSave = (event) => tslib_1.__awaiter(this, void 0, void 0, function* () { - console.log("saved", this.filePath); if (this.filePath !== event.path) { console.log("file path changed to", event.path); this.client = yield atomts_1.clientResolver.get(event.path); @@ -93,7 +83,6 @@ class TypescriptEditorPane { file: this.filePath }); this.opts.statusPanel.setBuildStatus(null); - console.log("Compile on Saving..."); const fileNames = lodash_1.flatten(result.body.map(project => project.fileNames)); if (fileNames.length === 0) { return; @@ -116,9 +105,21 @@ class TypescriptEditorPane { }); } }); - this.onDidStopChanging = () => { - console.log("did stop changing", this.filePath); + this.onDidStopChanging = ({ changes }) => { if (this.isTypescript && this.filePath) { + if (this.isOpen) { + this.opts.statusPanel.setBuildStatus(null); + for (const change of changes) { + this.client.executeChange({ + endLine: change.start.row + change.oldExtent.row + 1, + endOffset: change.start.column + change.oldExtent.column + 1, + file: this.filePath, + line: change.start.row + 1, + offset: change.start.column + 1, + insertString: change.newText, + }); + } + } this.client.executeGetErr({ files: [this.filePath], delay: 100 diff --git a/lib/client/client.ts b/lib/client/client.ts index 42ca29e5f..4bc2327c5 100644 --- a/lib/client/client.ts +++ b/lib/client/client.ts @@ -41,6 +41,7 @@ export class TypescriptServiceClient { compileOnSaveEmitFile: true, completionEntryDetails: true, completions: true, + definition: true, occurrences: true, projectInfo: true, quickinfo: true, @@ -65,6 +66,9 @@ export class TypescriptServiceClient { executeCompletionDetails(args: protocol.CompletionDetailsRequestArgs): Promise { return this.execute("completionEntryDetails", args) } + executeDefinition(args: protocol.FileLocationRequestArgs): Promise { + return this.execute("definition", args) + } executeGetErr(args: protocol.GeterrRequestArgs) { this.execute("geterr", args) } diff --git a/lib/main/atom/commands/commands.ts b/lib/main/atom/commands/commands.ts index a55bfad94..a75687273 100644 --- a/lib/main/atom/commands/commands.ts +++ b/lib/main/atom/commands/commands.ts @@ -1,19 +1,27 @@ -import {clientResolver} from "../../atomts" // import atomUtils = require("../atomUtils"); // import path = require('path'); // import renameView = require("../views/renameView"); // import fileSymbolsView = require("../views/fileSymbolsView"); // import projectSymbolsView = require("../views/projectSymbolsView"); -import {create as createTypeOverlay} from "../views/typeOverlayView"; -import gotoHistory = require("../gotoHistory"); +// import {create as createTypeOverlay} from "../views/typeOverlayView"; +// import gotoHistory = require("../gotoHistory"); // import utils = require("../../lang/utils"); // import {simpleSelectionView} from "../views/simpleSelectionView"; // import escapeHtml = require('escape-html'); // Load all the web components -export * from "../components/componentRegistry"; +// export * from "../components/componentRegistry"; -export function registerCommands() { +import {commands, Dependencies} from "./registry" + +// Import all of the command files for their side effects +import "./goToDeclaration" + +export function registerCommands(deps: Dependencies) { + + for (const [name, command] of commands) { + atom.commands.add("atom-workspace", name, command(deps)) + } // Setup custom commands NOTE: these need to be added to the keymaps // atom.commands.add('atom-text-editor', 'typescript:format-code', (e) => { @@ -40,49 +48,6 @@ export function registerCommands() { // } // }); - // atom.commands.add('atom-workspace', 'typescript:go-to-declaration', (e) => { - // if (!atomUtils.commandForTypeScript(e)) return; - - // 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) => { - // atom.workspace.open(definition.filePath, { - // initialLine: definition.position.line, - // initialColumn: definition.position.col - // }); - // } - // }) - // } - // else { - // var definition = definitions[0]; - - // atom.workspace.open(definition.filePath, { - // initialLine: definition.position.line, - // initialColumn: definition.position.col - // }); - // } - // }); - // }); - // atom.commands.add('atom-workspace', 'typescript:create-tsconfig.json-project-file', (e) => { // if (!atomUtils.commandForTypeScript(e)) return; @@ -150,56 +115,55 @@ export function registerCommands() { // } // }); - 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 = cursor.getBufferPosition() - var filePath = editor.getPath(); - - clientResolver.get(filePath).then(client => { - return client.executeQuickInfo({ - file: filePath, - line: position.row+1, - offset: position.column+1 - }).then(({body: {displayString, documentation}}) => { - var decoration = editor.decorateMarker(cursor.getMarker(), { - type: 'overlay', - item: createTypeOverlay(displayString, documentation) - }); - - 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); - }).catch(() => { /* ignore errors */ }) - }) - }); - - 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:show-type', (e) => { + // var editor = atom.workspace.getActiveTextEditor(); + // var editorView = atom.views.getView(editor); + // var cursor = editor.getLastCursor() + // var position = cursor.getBufferPosition() + // var filePath = editor.getPath(); + // + // clientResolver.get(filePath).then(client => { + // return client.executeQuickInfo({ + // file: filePath, + // line: position.row+1, + // offset: position.column+1 + // }).then(({body: {displayString, documentation}}) => { + // var decoration = editor.decorateMarker(cursor.getMarker(), { + // type: 'overlay', + // item: createTypeOverlay(displayString, documentation) + // }); + // + // 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); + // }).catch(() => { /* ignore errors */ }) + // }) + // }); + // + // 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) => { diff --git a/lib/main/atom/commands/goToDeclaration.ts b/lib/main/atom/commands/goToDeclaration.ts new file mode 100644 index 000000000..452c99ecd --- /dev/null +++ b/lib/main/atom/commands/goToDeclaration.ts @@ -0,0 +1,38 @@ +import {commands} from "./registry" +import {commandForTypeScript, getFilePathPosition} from "../atomUtils" +import {simpleSelectionView} from "../views/simpleSelectionView" + +commands.set("typescript:go-to-declaration", deps => { + return async e => { + if (!commandForTypeScript(e)) { + return + } + + const location = getFilePathPosition() + const client = await deps.clientResolver.get(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: open + }) + } else { + open(result.body[0]) + } + + function open(item: typeof result.body[0]) { + atom.workspace.open(item.file, { + initialLine: item.start.line - 1, + initialColumn: item.start.offset - 1 + }) + } + } +}) diff --git a/lib/main/atom/commands/registry.ts b/lib/main/atom/commands/registry.ts new file mode 100644 index 000000000..74964a89c --- /dev/null +++ b/lib/main/atom/commands/registry.ts @@ -0,0 +1,14 @@ +import {ClientResolver} from "../../../client/clientResolver" + +export interface Dependencies { + clientResolver: ClientResolver +} + +export interface CommandConstructor { + (deps: Dependencies): (e) => 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/atomts.ts b/lib/main/atomts.ts index e923e1488..f6eef15ad 100644 --- a/lib/main/atomts.ts +++ b/lib/main/atomts.ts @@ -72,7 +72,7 @@ export function activate(state: PackageState) { renameView.attach() // Register the commands - commands.registerCommands() + commands.registerCommands({clientResolver}) const panes: TypescriptEditorPane[] = [] diff --git a/lib/main/typescript_editor_pane.ts b/lib/main/typescript_editor_pane.ts index 1db1b67a3..8556efd81 100644 --- a/lib/main/typescript_editor_pane.ts +++ b/lib/main/typescript_editor_pane.ts @@ -197,7 +197,6 @@ export class TypescriptEditorPane implements AtomCore.Disposable { this.opts.statusPanel.setBuildStatus(null) - console.log("Compile on Saving...") const fileNames = flatten(result.body.map(project => project.fileNames)) if (fileNames.length === 0) { From 907b796b0a2b235ee85bd9c5e643cf24ade4dbb8 Mon Sep 17 00:00:00 2001 From: Guntars Asmanis-Graham Date: Thu, 22 Dec 2016 11:23:23 -0500 Subject: [PATCH 35/70] Fix some issues with the emit status, completions --- dist/main/atom/autoCompleteProvider.js | 13 +-------- dist/main/atom/commands/goToDeclaration.js | 2 +- dist/main/atom/components/statusPanel.js | 1 + dist/main/atomts.js | 19 +++++++++---- dist/main/typescript_editor_pane.js | 5 ++-- lib/main/atom/autoCompleteProvider.ts | 32 +++++++++++++--------- lib/main/atom/commands/goToDeclaration.ts | 2 +- lib/main/atom/commands/registry.ts | 4 +-- lib/main/atomts.ts | 20 ++++++++------ lib/main/typescript_editor_pane.ts | 7 +++-- 10 files changed, 57 insertions(+), 48 deletions(-) diff --git a/dist/main/atom/autoCompleteProvider.js b/dist/main/atom/autoCompleteProvider.js index 7dfaaee6c..d01eff9ea 100644 --- a/dist/main/atom/autoCompleteProvider.js +++ b/dist/main/atom/autoCompleteProvider.js @@ -13,14 +13,6 @@ class AutocompleteProvider { } getSuggestionsWithCache(prefix, location) { return tslib_1.__awaiter(this, void 0, void 0, function* () { - if (this.lastSuggestions) { - 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) { - return this.lastSuggestions.suggestions; - } - } const client = yield this.clientResolver.get(location.file); const completions = yield client.executeCompletions(tslib_1.__assign({ prefix }, location)); const suggestions = completions.body.map(entry => ({ @@ -41,6 +33,7 @@ class AutocompleteProvider { return tslib_1.__awaiter(this, void 0, void 0, function* () { const location = getLocationQuery(opts); const { prefix } = opts; + console.log("autocomplete", { prefix, location }); if (!location.file) { return []; } @@ -86,10 +79,6 @@ function getReplacementPrefix(prefix, replacement) { return prefix; } } -function getNormalizedCol(prefix, col) { - const length = prefix === "." ? 0 : prefix.length; - return col - length; -} function getLocationQuery(opts) { return { file: opts.editor.getPath(), diff --git a/dist/main/atom/commands/goToDeclaration.js b/dist/main/atom/commands/goToDeclaration.js index 7cdc20206..e37b607a1 100644 --- a/dist/main/atom/commands/goToDeclaration.js +++ b/dist/main/atom/commands/goToDeclaration.js @@ -9,7 +9,7 @@ registry_1.commands.set("typescript:go-to-declaration", deps => { return; } const location = atomUtils_1.getFilePathPosition(); - const client = yield deps.clientResolver.get(location.file); + const client = yield deps.getClient(location.file); const result = yield client.executeDefinition(location); if (result.body.length > 1) { simpleSelectionView_1.simpleSelectionView({ diff --git a/dist/main/atom/components/statusPanel.js b/dist/main/atom/components/statusPanel.js index 7c7adfa02..85ed39040 100644 --- a/dist/main/atom/components/statusPanel.js +++ b/dist/main/atom/components/statusPanel.js @@ -39,6 +39,7 @@ class StatusPanel extends HTMLElement { } } setBuildStatus(status) { + console.log("setting build status", status); const container = this.statusText; if (status) { if (status.success) { diff --git a/dist/main/atomts.js b/dist/main/atomts.js index 03cfeba6b..ef748ec52 100644 --- a/dist/main/atomts.js +++ b/dist/main/atomts.js @@ -1,7 +1,5 @@ "use strict"; -console.log("be initializing them package"); -console.profile("atomts init"); -const startTime = process.hrtime(); +const tslib_1 = require("tslib"); const clientResolver_1 = require("../client/clientResolver"); const atom_1 = require("atom"); const lodash_1 = require("lodash"); @@ -46,7 +44,18 @@ function activate(state) { }); } renameView.attach(); - commands.registerCommands({ clientResolver: exports.clientResolver }); + commands.registerCommands({ + getClient(filePath) { + return tslib_1.__awaiter(this, void 0, void 0, function* () { + for (const pane of panes) { + if (pane.filePath === filePath) { + return pane.client; + } + } + return exports.clientResolver.get(filePath); + }); + } + }); const panes = []; const onSave = lodash_1.debounce((pane) => { console.log("checking errors for all panes for", pane.filePath); @@ -126,5 +135,3 @@ function loadProjectConfig(sourcePath) { }); } exports.loadProjectConfig = loadProjectConfig; -console.profileEnd(); -console.log("init took", process.hrtime(startTime)); diff --git a/dist/main/typescript_editor_pane.js b/dist/main/typescript_editor_pane.js index 52b80aa8b..300e0a0ef 100644 --- a/dist/main/typescript_editor_pane.js +++ b/dist/main/typescript_editor_pane.js @@ -93,7 +93,6 @@ class TypescriptEditorPane { if (!saved.every(res => res.body)) { throw new Error("Some files failed to emit"); } - console.log("Saved....", saved); this.opts.statusPanel.setBuildStatus({ success: true }); @@ -108,7 +107,9 @@ class TypescriptEditorPane { this.onDidStopChanging = ({ changes }) => { if (this.isTypescript && this.filePath) { if (this.isOpen) { - this.opts.statusPanel.setBuildStatus(null); + if (changes.length !== 0) { + this.opts.statusPanel.setBuildStatus(null); + } for (const change of changes) { this.client.executeChange({ endLine: change.start.row + change.oldExtent.row + 1, diff --git a/lib/main/atom/autoCompleteProvider.ts b/lib/main/atom/autoCompleteProvider.ts index 45d6329e9..568c376d3 100644 --- a/lib/main/atom/autoCompleteProvider.ts +++ b/lib/main/atom/autoCompleteProvider.ts @@ -39,15 +39,19 @@ export class AutocompleteProvider implements Provider { prefix: string, location: FileLocationQuery ): Promise { - if (this.lastSuggestions) { - 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) { - return this.lastSuggestions.suggestions - } - } + // NOTE: While typing this can get out of sync with what tsserver would return so find a better + // way to reuse the completions. + // if (this.lastSuggestions) { + // 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 = await this.clientResolver.get(location.file) const completions = await client.executeCompletions({prefix, ...location}) @@ -72,6 +76,8 @@ export class AutocompleteProvider implements Provider { const location = getLocationQuery(opts) const {prefix} = opts + console.log("autocomplete", {prefix, location}) + if (!location.file) { return [] } @@ -130,10 +136,10 @@ function getReplacementPrefix(prefix: string, replacement: string): string { // 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 getNormalizedCol(prefix: string, col: number): number { +// const length = prefix === "." ? 0 : prefix.length +// return col - length +// } function getLocationQuery(opts: RequestOptions): FileLocationQuery { return { diff --git a/lib/main/atom/commands/goToDeclaration.ts b/lib/main/atom/commands/goToDeclaration.ts index 452c99ecd..53a751c51 100644 --- a/lib/main/atom/commands/goToDeclaration.ts +++ b/lib/main/atom/commands/goToDeclaration.ts @@ -9,7 +9,7 @@ commands.set("typescript:go-to-declaration", deps => { } const location = getFilePathPosition() - const client = await deps.clientResolver.get(location.file) + const client = await deps.getClient(location.file) const result = await client.executeDefinition(location) if (result.body.length > 1) { diff --git a/lib/main/atom/commands/registry.ts b/lib/main/atom/commands/registry.ts index 74964a89c..9fefa742d 100644 --- a/lib/main/atom/commands/registry.ts +++ b/lib/main/atom/commands/registry.ts @@ -1,7 +1,7 @@ -import {ClientResolver} from "../../../client/clientResolver" +import {TypescriptServiceClient} from "../../../client/client" export interface Dependencies { - clientResolver: ClientResolver + getClient(filePath: string): Promise } export interface CommandConstructor { diff --git a/lib/main/atomts.ts b/lib/main/atomts.ts index f6eef15ad..262d684b8 100644 --- a/lib/main/atomts.ts +++ b/lib/main/atomts.ts @@ -1,8 +1,3 @@ -console.log("be initializing them package") -console.profile("atomts init") - -const startTime = process.hrtime() - // import {getFileStatus} from "./atom/fileStatusCache" // import {$} from "atom-space-pen-views" import {ClientResolver} from "../client/clientResolver" @@ -72,7 +67,17 @@ export function activate(state: PackageState) { renameView.attach() // Register the commands - commands.registerCommands({clientResolver}) + commands.registerCommands({ + async getClient(filePath: string) { + for (const pane of panes) { + if (pane.filePath === filePath) { + return pane.client + } + } + + return clientResolver.get(filePath) + } + }) const panes: TypescriptEditorPane[] = [] @@ -166,6 +171,3 @@ export function loadProjectConfig(sourcePath: string): Promise { if (this.isTypescript && this.filePath) { if (this.isOpen) { - this.opts.statusPanel.setBuildStatus(null) + + if (changes.length !== 0) { + this.opts.statusPanel.setBuildStatus(null) + } + for (const change of changes) { this.client.executeChange({ endLine: change.start.row + change.oldExtent.row + 1, From 9f2f2ea0489ef9b645dc6fad1213b7ec1a0f6734 Mon Sep 17 00:00:00 2001 From: Guntars Asmanis-Graham Date: Thu, 22 Dec 2016 17:08:00 -0500 Subject: [PATCH 36/70] Fix server getting out of sync due to changes event --- dist/client/client.js | 7 +++++++ dist/main/atom/autoCompleteProvider.js | 7 ++++--- dist/main/atom/commands/commands.js | 2 ++ dist/main/atomts.js | 1 + dist/main/typescript_editor_pane.js | 14 ++++++-------- lib/client/client.ts | 7 +++++++ lib/main/atom/components/componentRegistry.ts | 1 - lib/main/typescript_editor_pane.ts | 16 +++++++++++----- 8 files changed, 38 insertions(+), 17 deletions(-) delete mode 100644 lib/main/atom/components/componentRegistry.ts diff --git a/dist/client/client.js b/dist/client/client.js index b11004ac0..a9e9377c8 100644 --- a/dist/client/client.js +++ b/dist/client/client.js @@ -69,9 +69,15 @@ class TypescriptServiceClient { executeQuickInfo(args) { return this.execute("quickinfo", args); } + executeReferences(args) { + return this.execute("references", args); + } executeReload(args) { return this.execute("reload", args); } + executeSaveTo(args) { + return this.execute("saveto", args); + } execute(command, args) { return this.serverPromise.then(cp => { const expectResponse = !!TypescriptServiceClient.commandWithResponse[command]; @@ -158,6 +164,7 @@ TypescriptServiceClient.commandWithResponse = { occurrences: true, projectInfo: true, quickinfo: true, + references: true, reload: true, }; exports.TypescriptServiceClient = TypescriptServiceClient; diff --git a/dist/main/atom/autoCompleteProvider.js b/dist/main/atom/autoCompleteProvider.js index d01eff9ea..d33cf6cd7 100644 --- a/dist/main/atom/autoCompleteProvider.js +++ b/dist/main/atom/autoCompleteProvider.js @@ -48,7 +48,8 @@ class AutocompleteProvider { suggestions = fuzzaldrin.filter(suggestions, alphaPrefix, { key: "text" }); } this.getAdditionalDetails(suggestions.slice(0, 15), location); - return suggestions.map(suggestion => (tslib_1.__assign({ replacementPrefix: getReplacementPrefix(prefix, suggestion.text) }, suggestion))); + const trimmed = prefix.trim(); + return suggestions.map(suggestion => (tslib_1.__assign({ replacementPrefix: getReplacementPrefix(prefix, trimmed, suggestion.text) }, suggestion))); }); } getAdditionalDetails(suggestions, location) { @@ -68,8 +69,8 @@ class AutocompleteProvider { } } exports.AutocompleteProvider = AutocompleteProvider; -function getReplacementPrefix(prefix, replacement) { - if (prefix === ".") { +function getReplacementPrefix(prefix, trimmed, replacement) { + if (trimmed === "." || trimmed === "{") { return ""; } else if (replacement.startsWith("$")) { diff --git a/dist/main/atom/commands/commands.js b/dist/main/atom/commands/commands.js index 0ac05a49f..5ec119d34 100644 --- a/dist/main/atom/commands/commands.js +++ b/dist/main/atom/commands/commands.js @@ -1,5 +1,7 @@ "use strict"; const registry_1 = require("./registry"); +require("./checkAllFiles"); +require("./findReferences"); require("./goToDeclaration"); function registerCommands(deps) { for (const [name, command] of registry_1.commands) { diff --git a/dist/main/atomts.js b/dist/main/atomts.js index ef748ec52..9e462d636 100644 --- a/dist/main/atomts.js +++ b/dist/main/atomts.js @@ -16,6 +16,7 @@ const lodash_2 = require("lodash"); const subscriptions = new atom_1.CompositeDisposable(); exports.clientResolver = new clientResolver_1.ClientResolver(); exports.config = atomConfig.schema; +require("./atom/components"); let linter; let statusBar; function activate(state) { diff --git a/dist/main/typescript_editor_pane.js b/dist/main/typescript_editor_pane.js index 300e0a0ef..8b391abd3 100644 --- a/dist/main/typescript_editor_pane.js +++ b/dist/main/typescript_editor_pane.js @@ -111,14 +111,12 @@ class TypescriptEditorPane { this.opts.statusPanel.setBuildStatus(null); } for (const change of changes) { - this.client.executeChange({ - endLine: change.start.row + change.oldExtent.row + 1, - endOffset: change.start.column + change.oldExtent.column + 1, - file: this.filePath, - line: change.start.row + 1, - offset: change.start.column + 1, - insertString: change.newText, - }); + const { start, oldExtent, newText } = change; + const end = { + endLine: start.row + oldExtent.row + 1, + endOffset: (oldExtent.row === 0 ? start.column + oldExtent.column : oldExtent.column) + 1 + }; + this.client.executeChange(tslib_1.__assign({}, end, { file: this.filePath, line: start.row + 1, offset: start.column + 1, insertString: newText })); } } this.client.executeGetErr({ diff --git a/lib/client/client.ts b/lib/client/client.ts index 4bc2327c5..8130be1d1 100644 --- a/lib/client/client.ts +++ b/lib/client/client.ts @@ -45,6 +45,7 @@ export class TypescriptServiceClient { occurrences: true, projectInfo: true, quickinfo: true, + references: true, reload: true, } @@ -87,9 +88,15 @@ export class TypescriptServiceClient { 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) } + executeSaveTo(args: protocol.SavetoRequestArgs) { + return this.execute("saveto", args) + } execute(command: string, args): Promise { return this.serverPromise.then(cp => { 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/typescript_editor_pane.ts b/lib/main/typescript_editor_pane.ts index 7beb9e25e..c2d696c24 100644 --- a/lib/main/typescript_editor_pane.ts +++ b/lib/main/typescript_editor_pane.ts @@ -232,13 +232,19 @@ export class TypescriptEditorPane implements AtomCore.Disposable { } 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 + } + this.client.executeChange({ - endLine: change.start.row + change.oldExtent.row + 1, - endOffset: change.start.column + change.oldExtent.column + 1, + ...end, file: this.filePath, - line: change.start.row + 1, - offset: change.start.column + 1, - insertString: change.newText, + line: start.row + 1, + offset: start.column + 1, + insertString: newText, }) } } From c2ee088d5916d760a91aacd6ba2efb02e71a9cb2 Mon Sep 17 00:00:00 2001 From: Guntars Asmanis-Graham Date: Thu, 22 Dec 2016 17:09:19 -0500 Subject: [PATCH 37/70] Add CheckAllFiles and FindReferences commands --- dist/main/atom/commands/checkAllFiles.js | 14 +++++++++ dist/main/atom/commands/findReferences.js | 34 +++++++++++++++++++++ dist/main/atom/components/index.js | 5 ++++ lib/main/atom/autoCompleteProvider.ts | 10 ++++--- lib/main/atom/commands/checkAllFiles.ts | 15 ++++++++++ lib/main/atom/commands/commands.ts | 27 ++--------------- lib/main/atom/commands/findReferences.ts | 36 +++++++++++++++++++++++ lib/main/atom/components/index.ts | 1 + lib/main/atomts.ts | 3 ++ 9 files changed, 116 insertions(+), 29 deletions(-) create mode 100644 dist/main/atom/commands/checkAllFiles.js create mode 100644 dist/main/atom/commands/findReferences.js create mode 100644 dist/main/atom/components/index.js create mode 100644 lib/main/atom/commands/checkAllFiles.ts create mode 100644 lib/main/atom/commands/findReferences.ts create mode 100644 lib/main/atom/components/index.ts diff --git a/dist/main/atom/commands/checkAllFiles.js b/dist/main/atom/commands/checkAllFiles.js new file mode 100644 index 000000000..0b1ba09af --- /dev/null +++ b/dist/main/atom/commands/checkAllFiles.js @@ -0,0 +1,14 @@ +"use strict"; +const tslib_1 = require("tslib"); +const registry_1 = require("./registry"); +const atomUtils_1 = require("../atomUtils"); +registry_1.commands.set("typescript:check-all-files", deps => { + return (e) => tslib_1.__awaiter(this, void 0, void 0, function* () { + if (!atomUtils_1.commandForTypeScript(e)) { + return; + } + const location = atomUtils_1.getFilePathPosition(); + const client = yield deps.getClient(location.file); + client.executeGetErrForProject({ file: location.file, delay: 0 }); + }); +}); diff --git a/dist/main/atom/commands/findReferences.js b/dist/main/atom/commands/findReferences.js new file mode 100644 index 000000000..d2010cfde --- /dev/null +++ b/dist/main/atom/commands/findReferences.js @@ -0,0 +1,34 @@ +"use strict"; +const tslib_1 = require("tslib"); +const registry_1 = require("./registry"); +const atomUtils_1 = require("../atomUtils"); +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 (!atomUtils_1.commandForTypeScript(e)) { + return; + } + const location = atomUtils_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: open + }); + function open(item) { + atom.workspace.open(item.file, { + initialLine: item.start.line - 1, + initialColumn: item.start.offset - 1 + }); + } + }); +}); diff --git a/dist/main/atom/components/index.js b/dist/main/atom/components/index.js new file mode 100644 index 000000000..d2905b34c --- /dev/null +++ b/dist/main/atom/components/index.js @@ -0,0 +1,5 @@ +"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/lib/main/atom/autoCompleteProvider.ts b/lib/main/atom/autoCompleteProvider.ts index 568c376d3..3851f8243 100644 --- a/lib/main/atom/autoCompleteProvider.ts +++ b/lib/main/atom/autoCompleteProvider.ts @@ -96,8 +96,10 @@ export class AutocompleteProvider implements Provider { // Get additional details for the first few suggestions, but don't wait for it to complete this.getAdditionalDetails(suggestions.slice(0, 15), location) + const trimmed = prefix.trim() + return suggestions.map(suggestion => ({ - replacementPrefix: getReplacementPrefix(prefix, suggestion.text), + replacementPrefix: getReplacementPrefix(prefix, trimmed, suggestion.text), ...suggestion })) } @@ -123,9 +125,9 @@ export class AutocompleteProvider implements Provider { } } -// If prefix is ".", don't replace anything, just insert the completion, replace it otherwise. -function getReplacementPrefix(prefix: string, replacement: string): string { - if (prefix === ".") { +// 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 === "{") { return "" } else if (replacement.startsWith("$")) { return "$" + prefix diff --git a/lib/main/atom/commands/checkAllFiles.ts b/lib/main/atom/commands/checkAllFiles.ts new file mode 100644 index 000000000..05a85bfdc --- /dev/null +++ b/lib/main/atom/commands/checkAllFiles.ts @@ -0,0 +1,15 @@ +import {commands} from "./registry" +import {commandForTypeScript, getFilePathPosition} from "../atomUtils" + +commands.set("typescript:check-all-files", deps => { + return async e => { + if (!commandForTypeScript(e)) { + return + } + + const location = getFilePathPosition() + const client = await deps.getClient(location.file) + + client.executeGetErrForProject({file: location.file, delay: 0}) + } +}) diff --git a/lib/main/atom/commands/commands.ts b/lib/main/atom/commands/commands.ts index a75687273..232e05685 100644 --- a/lib/main/atom/commands/commands.ts +++ b/lib/main/atom/commands/commands.ts @@ -15,6 +15,8 @@ import {commands, Dependencies} from "./registry" // Import all of the command files for their side effects +import "./checkAllFiles" +import "./findReferences" import "./goToDeclaration" export function registerCommands(deps: Dependencies) { @@ -159,31 +161,6 @@ export function registerCommands(deps: Dependencies) { // gotoHistory.gotoPrevious(); // }); - // atom.commands.add('atom-workspace', 'typescript:find-references', (e) => { - // if (!atomUtils.commandForTypeScript(e)) return; - // - // parent.getReferences(atomUtils.getFilePathPosition()).then(res=> { - // - // 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; diff --git a/lib/main/atom/commands/findReferences.ts b/lib/main/atom/commands/findReferences.ts new file mode 100644 index 000000000..905752dd9 --- /dev/null +++ b/lib/main/atom/commands/findReferences.ts @@ -0,0 +1,36 @@ +import {commands} from "./registry" +import {commandForTypeScript, getFilePathPosition} from "../atomUtils" +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: open + }) + + function open(item: typeof result.body.refs[0]) { + atom.workspace.open(item.file, { + initialLine: item.start.line - 1, + initialColumn: item.start.offset - 1 + }) + } + } +}) diff --git a/lib/main/atom/components/index.ts b/lib/main/atom/components/index.ts new file mode 100644 index 000000000..ec148a328 --- /dev/null +++ b/lib/main/atom/components/index.ts @@ -0,0 +1 @@ +export * from "./ts-view"; diff --git a/lib/main/atomts.ts b/lib/main/atomts.ts index 262d684b8..a6906ec48 100644 --- a/lib/main/atomts.ts +++ b/lib/main/atomts.ts @@ -24,6 +24,9 @@ const subscriptions = new CompositeDisposable() export const clientResolver = new ClientResolver() export const config = atomConfig.schema +// Register all custom components +import "./atom/components" + let linter: Linter let statusBar: StatusBar From 3ceb31a8d65db4ce3c8a378a9d75bc8ea00cb313 Mon Sep 17 00:00:00 2001 From: Guntars Asmanis-Graham Date: Thu, 22 Dec 2016 19:00:04 -0500 Subject: [PATCH 38/70] add ClearErrors command, show progress while checking all files --- dist/main/atom/autoCompleteProvider.js | 2 +- dist/main/atom/commands/checkAllFiles.js | 33 ++++++++++++-- dist/main/atom/commands/clearErrors.js | 7 +++ dist/main/atom/commands/index.js | 15 +++++++ dist/main/atom/components/statusBar.js | 16 ------- dist/main/atom/components/statusPanel.js | 15 ++++++- dist/main/atomts.js | 17 +++++--- dist/main/error_pusher.js | 2 +- lib/main/atom/autoCompleteProvider.ts | 2 +- lib/main/atom/commands/checkAllFiles.ts | 43 +++++++++++++++++-- lib/main/atom/commands/clearErrors.ts | 7 +++ .../atom/commands/{commands.ts => index.ts} | 1 + lib/main/atom/commands/registry.ts | 3 ++ lib/main/atom/components/statusPanel.tsx | 17 +++++++- lib/main/atomts.ts | 18 +++++--- lib/main/error_pusher.ts | 5 +-- 16 files changed, 162 insertions(+), 41 deletions(-) create mode 100644 dist/main/atom/commands/clearErrors.js create mode 100644 dist/main/atom/commands/index.js delete mode 100644 dist/main/atom/components/statusBar.js create mode 100644 lib/main/atom/commands/clearErrors.ts rename lib/main/atom/commands/{commands.ts => index.ts} (99%) diff --git a/dist/main/atom/autoCompleteProvider.js b/dist/main/atom/autoCompleteProvider.js index d33cf6cd7..e26573394 100644 --- a/dist/main/atom/autoCompleteProvider.js +++ b/dist/main/atom/autoCompleteProvider.js @@ -70,7 +70,7 @@ class AutocompleteProvider { } exports.AutocompleteProvider = AutocompleteProvider; function getReplacementPrefix(prefix, trimmed, replacement) { - if (trimmed === "." || trimmed === "{") { + if (trimmed === "." || trimmed === "{" || prefix === " ") { return ""; } else if (replacement.startsWith("$")) { diff --git a/dist/main/atom/commands/checkAllFiles.js b/dist/main/atom/commands/checkAllFiles.js index 0b1ba09af..e3d4264ed 100644 --- a/dist/main/atom/commands/checkAllFiles.js +++ b/dist/main/atom/commands/checkAllFiles.js @@ -7,8 +7,35 @@ registry_1.commands.set("typescript:check-all-files", deps => { if (!atomUtils_1.commandForTypeScript(e)) { return; } - const location = atomUtils_1.getFilePathPosition(); - const client = yield deps.getClient(location.file); - client.executeGetErrForProject({ file: location.file, delay: 0 }); + const { file } = atomUtils_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; + 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(null); + } + else { + deps.statusPanel.setProgress({ max, value: max - files.size }); + } + } }); }); diff --git a/dist/main/atom/commands/clearErrors.js b/dist/main/atom/commands/clearErrors.js new file mode 100644 index 000000000..642c79800 --- /dev/null +++ b/dist/main/atom/commands/clearErrors.js @@ -0,0 +1,7 @@ +"use strict"; +const registry_1 = require("./registry"); +registry_1.commands.set("typescript:clear-errors", deps => { + return e => { + deps.clearErrors(); + }; +}); diff --git a/dist/main/atom/commands/index.js b/dist/main/atom/commands/index.js new file mode 100644 index 000000000..0b6470766 --- /dev/null +++ b/dist/main/atom/commands/index.js @@ -0,0 +1,15 @@ +"use strict"; +const registry_1 = require("./registry"); +require("./checkAllFiles"); +require("./clearErrors"); +require("./findReferences"); +require("./goToDeclaration"); +function registerCommands(deps) { + for (const [name, command] of registry_1.commands) { + atom.commands.add("atom-workspace", name, command(deps)); + } + atom.commands.add('atom-workspace', 'typescript:sync', (e) => { + console.log("typescript:sync trigerred"); + }); +} +exports.registerCommands = registerCommands; diff --git a/dist/main/atom/components/statusBar.js b/dist/main/atom/components/statusBar.js deleted file mode 100644 index 4bbe21009..000000000 --- a/dist/main/atom/components/statusBar.js +++ /dev/null @@ -1,16 +0,0 @@ -"use strict"; -const tslib_1 = require("tslib"); -class StatusPanel extends HTMLElement { - createdCallback() { - console.log("created"); - this.innerHTML = "Ay karamba!"; - } - attachedCallback() { - console.log("attached"); - } - attributeChangedCallback() { - console.log("attrs changed", arguments); - } -} -exports.StatusPanel = StatusPanel; -document.registerElement('ts-status-panel', StatusPanel); diff --git a/dist/main/atom/components/statusPanel.js b/dist/main/atom/components/statusPanel.js index 85ed39040..655bcbd08 100644 --- a/dist/main/atom/components/statusPanel.js +++ b/dist/main/atom/components/statusPanel.js @@ -17,7 +17,8 @@ class StatusPanel extends HTMLElement { this.openConfigPath(); } }), dom.createElement("div", { ref: el => this.statusContainer = el, className: "inline-block" }, - dom.createElement("span", { ref: el => this.statusText = el })) + 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); @@ -26,6 +27,7 @@ class StatusPanel extends HTMLElement { this.setPending([], true); this.setTsConfigPath(null); this.setBuildStatus(null); + this.setProgress(null); } dispose() { this.remove(); @@ -39,7 +41,6 @@ class StatusPanel extends HTMLElement { } } setBuildStatus(status) { - console.log("setting build status", status); const container = this.statusText; if (status) { if (status.success) { @@ -58,6 +59,16 @@ class StatusPanel extends HTMLElement { 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) { diff --git a/dist/main/atomts.js b/dist/main/atomts.js index 9e462d636..808d105bd 100644 --- a/dist/main/atomts.js +++ b/dist/main/atomts.js @@ -8,7 +8,6 @@ const typescript_editor_pane_1 = require("./typescript_editor_pane"); const statusPanel_1 = require("./atom/components/statusPanel"); const atomConfig = require("./atom/atomConfig"); const autoCompleteProvider_1 = require("./atom/autoCompleteProvider"); -const commands = require("./atom/commands/commands"); const hyperclickProvider = require("../hyperclickProvider"); const renameView = require("./atom/views/renameView"); const tsconfig = require("tsconfig/dist/tsconfig"); @@ -17,6 +16,7 @@ const subscriptions = new atom_1.CompositeDisposable(); exports.clientResolver = new clientResolver_1.ClientResolver(); exports.config = atomConfig.schema; require("./atom/components"); +const commands_1 = require("./atom/commands"); let linter; let statusBar; function activate(state) { @@ -40,12 +40,15 @@ function activate(state) { }); if (linter) { errorPusher.setLinter(linter); - exports.clientResolver.on("diagnostics", ({ type, serverPath, filePath, diagnostics }) => { - errorPusher.addErrors(type + serverPath, filePath, diagnostics); + exports.clientResolver.on("diagnostics", ({ type, filePath, diagnostics }) => { + errorPusher.setErrors(type, filePath, diagnostics); }); } renameView.attach(); - commands.registerCommands({ + commands_1.registerCommands({ + clearErrors() { + errorPusher.clear(); + }, getClient(filePath) { return tslib_1.__awaiter(this, void 0, void 0, function* () { for (const pane of panes) { @@ -55,7 +58,8 @@ function activate(state) { } return exports.clientResolver.get(filePath); }); - } + }, + statusPanel, }); const panes = []; const onSave = lodash_1.debounce((pane) => { @@ -73,6 +77,9 @@ function activate(state) { activePane = null; } panes.splice(panes.indexOf(pane), 1); + console.log("closing", pane.filePath); + errorPusher.setErrors("syntaxDiag", pane.filePath, []); + errorPusher.setErrors("semanticDiag", pane.filePath, []); }, onSave, statusPanel, diff --git a/dist/main/error_pusher.js b/dist/main/error_pusher.js index 584d22769..90aba8f77 100644 --- a/dist/main/error_pusher.js +++ b/dist/main/error_pusher.js @@ -23,7 +23,7 @@ class ErrorPusher { } }, 100); } - addErrors(prefix, filePath, errors) { + setErrors(prefix, filePath, errors) { let prefixed = this.errors.get(prefix); if (!prefixed) { prefixed = new Map(); diff --git a/lib/main/atom/autoCompleteProvider.ts b/lib/main/atom/autoCompleteProvider.ts index 3851f8243..b2b31089b 100644 --- a/lib/main/atom/autoCompleteProvider.ts +++ b/lib/main/atom/autoCompleteProvider.ts @@ -127,7 +127,7 @@ export class AutocompleteProvider implements Provider { // 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 === "{") { + if (trimmed === "." || trimmed === "{" || prefix === " ") { return "" } else if (replacement.startsWith("$")) { return "$" + prefix diff --git a/lib/main/atom/commands/checkAllFiles.ts b/lib/main/atom/commands/checkAllFiles.ts index 05a85bfdc..884a2a2f1 100644 --- a/lib/main/atom/commands/checkAllFiles.ts +++ b/lib/main/atom/commands/checkAllFiles.ts @@ -7,9 +7,46 @@ commands.set("typescript:check-all-files", deps => { return } - const location = getFilePathPosition() - const client = await deps.getClient(location.file) + const {file} = getFilePathPosition() + const client = await deps.getClient(file) - client.executeGetErrForProject({file: location.file, delay: 0}) + 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 + + 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(null) + } 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/index.ts similarity index 99% rename from lib/main/atom/commands/commands.ts rename to lib/main/atom/commands/index.ts index 232e05685..38e2fcf14 100644 --- a/lib/main/atom/commands/commands.ts +++ b/lib/main/atom/commands/index.ts @@ -16,6 +16,7 @@ import {commands, Dependencies} from "./registry" // Import all of the command files for their side effects import "./checkAllFiles" +import "./clearErrors" import "./findReferences" import "./goToDeclaration" diff --git a/lib/main/atom/commands/registry.ts b/lib/main/atom/commands/registry.ts index 9fefa742d..4410c2ed3 100644 --- a/lib/main/atom/commands/registry.ts +++ b/lib/main/atom/commands/registry.ts @@ -1,7 +1,10 @@ import {TypescriptServiceClient} from "../../../client/client" +import {StatusPanel} from "../../atom/components/statusPanel" export interface Dependencies { + clearErrors() getClient(filePath: string): Promise + statusPanel: StatusPanel } export interface CommandConstructor { diff --git a/lib/main/atom/components/statusPanel.tsx b/lib/main/atom/components/statusPanel.tsx index f45d40cc2..6f431d874 100644 --- a/lib/main/atom/components/statusPanel.tsx +++ b/lib/main/atom/components/statusPanel.tsx @@ -11,6 +11,7 @@ export class StatusPanel extends HTMLElement { private pendingCounter: HTMLElement private pendingSpinner: HTMLElement private configPathContainer: HTMLElement + private progress: HTMLProgressElement private statusContainer: HTMLElement private statusText: HTMLElement private version: HTMLElement @@ -45,7 +46,10 @@ export class StatusPanel extends HTMLElement {
    this.statusContainer = el } className="inline-block"> this.statusText = el } /> -
    +
    , + this.progress = el } + style={{ verticalAlign: "baseline" }} + className='inline-block' /> ] for (const node of nodes) { @@ -56,6 +60,7 @@ export class StatusPanel extends HTMLElement { this.setPending([], true) this.setTsConfigPath(null) this.setBuildStatus(null) + this.setProgress(null) } dispose() { @@ -88,6 +93,16 @@ export class StatusPanel extends HTMLElement { } } + 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 diff --git a/lib/main/atomts.ts b/lib/main/atomts.ts index a6906ec48..aa1140027 100644 --- a/lib/main/atomts.ts +++ b/lib/main/atomts.ts @@ -11,7 +11,6 @@ import {StatusPanel} from "./atom/components/statusPanel" import * as atomConfig from './atom/atomConfig' // import * as atomUtils from './atom/atomUtils' import {AutocompleteProvider} from './atom/autoCompleteProvider' -import * as commands from "./atom/commands/commands" // import * as fs from 'fs' import * as hyperclickProvider from "../hyperclickProvider" // import * as path from 'path' @@ -26,6 +25,7 @@ export const config = atomConfig.schema // Register all custom components import "./atom/components" +import {registerCommands} from "./atom/commands" let linter: Linter let statusBar: StatusBar @@ -61,8 +61,8 @@ export function activate(state: PackageState) { if (linter) { errorPusher.setLinter(linter) - clientResolver.on("diagnostics", ({type, serverPath, filePath, diagnostics}) => { - errorPusher.addErrors(type + serverPath, filePath, diagnostics) + clientResolver.on("diagnostics", ({type, filePath, diagnostics}) => { + errorPusher.setErrors(type, filePath, diagnostics) }) } @@ -70,7 +70,10 @@ export function activate(state: PackageState) { renameView.attach() // Register the commands - commands.registerCommands({ + registerCommands({ + clearErrors() { + errorPusher.clear() + }, async getClient(filePath: string) { for (const pane of panes) { if (pane.filePath === filePath) { @@ -79,7 +82,8 @@ export function activate(state: PackageState) { } return clientResolver.get(filePath) - } + }, + statusPanel, }) const panes: TypescriptEditorPane[] = [] @@ -104,6 +108,10 @@ export function activate(state: PackageState) { } 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, diff --git a/lib/main/error_pusher.ts b/lib/main/error_pusher.ts index da4288e6b..14e1f2b97 100644 --- a/lib/main/error_pusher.ts +++ b/lib/main/error_pusher.ts @@ -8,8 +8,8 @@ export class ErrorPusher { private linter?: Linter private errors: Map> = new Map() - /** Add errors. Previous errors with the same prefix and filePath are going to be replaced */ - addErrors(prefix: string, filePath: string, errors: Diagnostic[]) { + /** Set errors. Previous errors with the same prefix and filePath are going to be replaced */ + setErrors(prefix: string, filePath: string, errors: Diagnostic[]) { let prefixed = this.errors.get(prefix) if (!prefixed) { prefixed = new Map() @@ -52,6 +52,5 @@ export class ErrorPusher { if (this.linter) { this.linter.setMessages(errors) } - }, 100) } From e1cccbe1256f98bc22adee184ee99421fc8e08d2 Mon Sep 17 00:00:00 2001 From: Guntars Asmanis-Graham Date: Thu, 22 Dec 2016 19:27:41 -0500 Subject: [PATCH 39/70] Add Build command --- dist/main/atom/commands/build.js | 45 ++++++++++++++ dist/main/atom/commands/commands.js | 14 ----- dist/main/atom/commands/index.js | 1 + .../main/atom/components/componentRegistry.js | 5 -- dist/main/atom/views/contextView.js | 53 ----------------- dist/main/atomts.js | 1 - dist/main/utils/dom.js | 58 ------------------- lib/main/atom/commands/build.ts | 53 +++++++++++++++++ lib/main/atom/commands/index.ts | 1 + 9 files changed, 100 insertions(+), 131 deletions(-) create mode 100644 dist/main/atom/commands/build.js delete mode 100644 dist/main/atom/commands/commands.js delete mode 100644 dist/main/atom/components/componentRegistry.js delete mode 100644 dist/main/atom/views/contextView.js delete mode 100644 dist/main/utils/dom.js create mode 100644 lib/main/atom/commands/build.ts diff --git a/dist/main/atom/commands/build.js b/dist/main/atom/commands/build.js new file mode 100644 index 000000000..b7fab132a --- /dev/null +++ b/dist/main/atom/commands/build.js @@ -0,0 +1,45 @@ +"use strict"; +const tslib_1 = require("tslib"); +const registry_1 = require("./registry"); +const atomUtils_1 = require("../atomUtils"); +registry_1.commands.set("typescript:build", deps => { + return (e) => tslib_1.__awaiter(this, void 0, void 0, function* () { + if (!atomUtils_1.commandForTypeScript(e)) { + return; + } + const { file } = atomUtils_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(null); + deps.statusPanel.setProgress({ max, value: 0 }); + function updateStatus() { + if (files.size === 0) { + deps.statusPanel.setProgress(null); + } + else { + deps.statusPanel.setProgress({ max, value: max - files.size }); + } + } + }); +}); +function _finally(promise, callback) { + promise.then(callback, callback); + return promise; +} diff --git a/dist/main/atom/commands/commands.js b/dist/main/atom/commands/commands.js deleted file mode 100644 index 5ec119d34..000000000 --- a/dist/main/atom/commands/commands.js +++ /dev/null @@ -1,14 +0,0 @@ -"use strict"; -const registry_1 = require("./registry"); -require("./checkAllFiles"); -require("./findReferences"); -require("./goToDeclaration"); -function registerCommands(deps) { - for (const [name, command] of registry_1.commands) { - atom.commands.add("atom-workspace", name, command(deps)); - } - atom.commands.add('atom-workspace', 'typescript:sync', (e) => { - console.log("typescript:sync trigerred"); - }); -} -exports.registerCommands = registerCommands; diff --git a/dist/main/atom/commands/index.js b/dist/main/atom/commands/index.js index 0b6470766..bc0f7137f 100644 --- a/dist/main/atom/commands/index.js +++ b/dist/main/atom/commands/index.js @@ -1,5 +1,6 @@ "use strict"; const registry_1 = require("./registry"); +require("./build"); require("./checkAllFiles"); require("./clearErrors"); require("./findReferences"); 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/views/contextView.js b/dist/main/atom/views/contextView.js deleted file mode 100644 index 138e341bf..000000000 --- a/dist/main/atom/views/contextView.js +++ /dev/null @@ -1,53 +0,0 @@ -"use strict"; -const tslib_1 = require("tslib"); -const sp = require("atom-space-pen-views"); -const mainPanelView = require("./mainPanelView"); -var titles = { - togglePanel: 'Toggle TypeScript Panel', - tabErrors: 'Tab: Errors in Open Files', - tabLastBuild: 'Tab: Last Build Output', - tabReferences: 'Tab: Find References', -}; -var items = Object.keys(titles).map(item => { return { title: titles[item] }; }); -class ContextView extends sp.SelectListView { - constructor() { - super(...arguments); - this.panel = null; - } - get $() { - return this; - } - setItems(items) { super.setItems(items); } - viewForItem(item) { - return `
  • ${item.title}
  • `; - } - confirmed(item) { - if (item.title == titles.togglePanel) { - mainPanelView.panelView.toggle(); - } - if (item.title == titles.tabLastBuild) { - mainPanelView.panelView.buildPanelSelected(); - } - if (item.title == titles.tabReferences) { - mainPanelView.panelView.referencesPanelSelected(); - } - this.hide(); - } - getFilterKey() { return 'title'; } - 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(); - } -} -exports.ContextView = ContextView; diff --git a/dist/main/atomts.js b/dist/main/atomts.js index 808d105bd..49c57152f 100644 --- a/dist/main/atomts.js +++ b/dist/main/atomts.js @@ -77,7 +77,6 @@ function activate(state) { activePane = null; } panes.splice(panes.indexOf(pane), 1); - console.log("closing", pane.filePath); errorPusher.setErrors("syntaxDiag", pane.filePath, []); errorPusher.setErrors("semanticDiag", pane.filePath, []); }, diff --git a/dist/main/utils/dom.js b/dist/main/utils/dom.js deleted file mode 100644 index e401796cd..000000000 --- a/dist/main/utils/dom.js +++ /dev/null @@ -1,58 +0,0 @@ -"use strict"; -function createElement(name, props, ...children) { - if (typeof name !== "string") { - throw new Error("String tag name expected"); - } - const element = document.createElement(name); - if (props) { - for (let attr in props) { - if (attr === "ref") { - if (typeof props[attr] !== "function") { - throw new Error("Ref attribute value should be a function"); - } - var ref = props[attr]; - continue; - } - else if (attr === "key") { - continue; - } - const value = props[attr]; - if (attr.startsWith("on") && attr[2] && attr[2] === attr[2].toUpperCase()) { - attr = attr.toLowerCase(); - } - else if (attr === "style") { - if (typeof value === "object" && value) { - const style = element.style; - for (const prop in value) { - if (typeof value[prop] === "number") { - style[prop] = value[prop] + "px"; - } - else { - style[prop] = value[prop]; - } - } - } - break; - } - element[attr] = value; - } - } - for (const child of children) { - if (typeof child === "string" || typeof child === "number") { - element.appendChild(document.createTextNode(child.toString())); - } - else if (child instanceof HTMLElement) { - element.appendChild(child); - } - else if (child === null || child === undefined) { - } - else { - throw new Error("Unknown child type: " + child); - } - } - if (ref) { - ref(element); - } - return element; -} -exports.createElement = createElement; diff --git a/lib/main/atom/commands/build.ts b/lib/main/atom/commands/build.ts new file mode 100644 index 000000000..65a602467 --- /dev/null +++ b/lib/main/atom/commands/build.ts @@ -0,0 +1,53 @@ +import {commands} from "./registry" +import {commandForTypeScript, getFilePathPosition} from "../atomUtils" + +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(null) + deps.statusPanel.setProgress({max, value: 0}) + + function updateStatus() { + if (files.size === 0) { + deps.statusPanel.setProgress(null) + } else { + deps.statusPanel.setProgress({max, value: max - files.size}) + } + } + } +}) + +function _finally(promise: Promise, callback: (result) => any): Promise { + promise.then(callback, callback) + return promise +} diff --git a/lib/main/atom/commands/index.ts b/lib/main/atom/commands/index.ts index 38e2fcf14..bb0637816 100644 --- a/lib/main/atom/commands/index.ts +++ b/lib/main/atom/commands/index.ts @@ -15,6 +15,7 @@ import {commands, Dependencies} from "./registry" // Import all of the command files for their side effects +import "./build" import "./checkAllFiles" import "./clearErrors" import "./findReferences" From 66b4cc53de51221564b30610d6f10610bed623a2 Mon Sep 17 00:00:00 2001 From: Guntars Asmanis-Graham Date: Sat, 24 Dec 2016 21:09:04 -0500 Subject: [PATCH 40/70] Implement basic rename refactor --- dist/client/client.js | 4 ++ dist/main/atom/commands/index.js | 1 + dist/main/atom/commands/renameRefactor.js | 46 +++++++++++++++++++ dist/main/atom/views/renameView.js | 32 +++++++++---- dist/main/atomts.js | 37 ++++++++++++--- lib/client/client.ts | 4 ++ lib/main/atom/commands/index.ts | 55 +---------------------- lib/main/atom/commands/registry.ts | 3 ++ lib/main/atom/commands/renameRefactor.ts | 49 ++++++++++++++++++++ lib/main/atom/views/renameView.ts | 52 ++++++++++++++------- lib/main/atomts.ts | 42 +++++++++++++---- lib/typings/atom.d.ts | 7 +++ lib/typings/atom_core.d.ts | 4 +- views/renameView.html.coffee | 2 - 14 files changed, 243 insertions(+), 95 deletions(-) create mode 100644 dist/main/atom/commands/renameRefactor.js create mode 100644 lib/main/atom/commands/renameRefactor.ts diff --git a/dist/client/client.js b/dist/client/client.js index a9e9377c8..d8bf9cdf0 100644 --- a/dist/client/client.js +++ b/dist/client/client.js @@ -75,6 +75,9 @@ class TypescriptServiceClient { executeReload(args) { return this.execute("reload", args); } + executeRename(args) { + return this.execute("rename", args); + } executeSaveTo(args) { return this.execute("saveto", args); } @@ -166,6 +169,7 @@ TypescriptServiceClient.commandWithResponse = { quickinfo: true, references: true, reload: true, + rename: true, }; exports.TypescriptServiceClient = TypescriptServiceClient; function isEvent(res) { diff --git a/dist/main/atom/commands/index.js b/dist/main/atom/commands/index.js index bc0f7137f..10245abe6 100644 --- a/dist/main/atom/commands/index.js +++ b/dist/main/atom/commands/index.js @@ -5,6 +5,7 @@ require("./checkAllFiles"); require("./clearErrors"); 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)); diff --git a/dist/main/atom/commands/renameRefactor.js b/dist/main/atom/commands/renameRefactor.js new file mode 100644 index 000000000..9507ab6a3 --- /dev/null +++ b/dist/main/atom/commands/renameRefactor.js @@ -0,0 +1,46 @@ +"use strict"; +const tslib_1 = require("tslib"); +const registry_1 = require("./registry"); +const atomUtils_1 = require("../atomUtils"); +const tsUtil_1 = require("./../../utils/tsUtil"); +registry_1.commands.set("typescript:rename-refactor", deps => { + return (e) => tslib_1.__awaiter(this, void 0, void 0, function* () { + if (!atomUtils_1.commandForTypeScript(e)) { + return; + } + const location = atomUtils_1.getFilePathPosition(); + const client = yield deps.getClient(location.file); + const { body: { info, locs } } = yield client.executeRename(location); + 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.getBuffer(loc.file); + buffer.transact(() => { + for (const span of loc.locs) { + buffer.setTextInRange(tsUtil_1.spanToRange(span), newName); + } + }); + if (!isOpen) { + buffer.save(); + buffer.onDidSave(() => { + buffer.destroy(); + }); + } + })); + }); +}); diff --git a/dist/main/atom/views/renameView.js b/dist/main/atom/views/renameView.js index 878cb9f49..52502f68c 100644 --- a/dist/main/atom/views/renameView.js +++ b/dist/main/atom/views/renameView.js @@ -1,4 +1,5 @@ "use strict"; +const tslib_1 = require("tslib"); const view = require("./view"); var $ = view.$; var html = require('../../../../views/renameView.html'); @@ -39,19 +40,22 @@ class RenameView extends view.View { } }); } + 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; } 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(); @@ -62,16 +66,28 @@ class RenameView extends view.View { 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} ) -
    `); + } + showRenameDialog(options) { + return new Promise((resolve, reject) => { + this.renameThis(tslib_1.__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; diff --git a/dist/main/atomts.js b/dist/main/atomts.js index 49c57152f..837c2aa38 100644 --- a/dist/main/atomts.js +++ b/dist/main/atomts.js @@ -9,9 +9,10 @@ const statusPanel_1 = require("./atom/components/statusPanel"); const atomConfig = require("./atom/atomConfig"); const autoCompleteProvider_1 = require("./atom/autoCompleteProvider"); const hyperclickProvider = require("../hyperclickProvider"); -const renameView = require("./atom/views/renameView"); +const renameView_1 = require("./atom/views/renameView"); const tsconfig = require("tsconfig/dist/tsconfig"); const lodash_2 = require("lodash"); +const Atom = require("atom"); const subscriptions = new atom_1.CompositeDisposable(); exports.clientResolver = new clientResolver_1.ClientResolver(); exports.config = atomConfig.schema; @@ -27,6 +28,7 @@ function activate(state) { statusPriority = panel.getPriority() - 1; } } + const { renameView } = renameView_1.attach(); const statusPanel = statusPanel_1.StatusPanel.create(); statusBar.addRightTile({ item: statusPanel, @@ -44,21 +46,44 @@ function activate(state) { errorPusher.setErrors(type, filePath, diagnostics); }); } - renameView.attach(); commands_1.registerCommands({ clearErrors() { errorPusher.clear(); }, + getBuffer(filePath) { + return tslib_1.__awaiter(this, void 0, void 0, function* () { + const pane = panes.find(pane => pane.filePath === filePath); + if (pane) { + return { + buffer: pane.editor.buffer, + isOpen: true + }; + } + const buffer = yield new Promise(resolve => { + const buffer = new Atom.TextBuffer({ + filePath, + load: true + }); + buffer.onDidReload(() => { + resolve(buffer); + }); + }); + return { + buffer, + isOpen: false + }; + }); + }, getClient(filePath) { return tslib_1.__awaiter(this, void 0, void 0, function* () { - for (const pane of panes) { - if (pane.filePath === filePath) { - return pane.client; - } + const pane = panes.find(pane => pane.filePath === filePath); + if (pane) { + return pane.client; } return exports.clientResolver.get(filePath); }); }, + renameView, statusPanel, }); const panes = []; diff --git a/lib/client/client.ts b/lib/client/client.ts index 8130be1d1..f4f3e376a 100644 --- a/lib/client/client.ts +++ b/lib/client/client.ts @@ -47,6 +47,7 @@ export class TypescriptServiceClient { quickinfo: true, references: true, reload: true, + rename: true, } executeChange(args: protocol.ChangeRequestArgs) { @@ -94,6 +95,9 @@ export class TypescriptServiceClient { 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) } diff --git a/lib/main/atom/commands/index.ts b/lib/main/atom/commands/index.ts index bb0637816..3bb4dc8bc 100644 --- a/lib/main/atom/commands/index.ts +++ b/lib/main/atom/commands/index.ts @@ -20,6 +20,7 @@ import "./checkAllFiles" import "./clearErrors" import "./findReferences" import "./goToDeclaration" +import "./renameRefactor" export function registerCommands(deps: Dependencies) { @@ -65,60 +66,6 @@ export function registerCommands(deps: Dependencies) { // }); // }); - // atom.commands.add('atom-text-editor', 'typescript:rename-refactor', (e) => { - // // Rename variable - // if (true) { - // 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); diff --git a/lib/main/atom/commands/registry.ts b/lib/main/atom/commands/registry.ts index 4410c2ed3..1fac9a12c 100644 --- a/lib/main/atom/commands/registry.ts +++ b/lib/main/atom/commands/registry.ts @@ -1,9 +1,12 @@ import {TypescriptServiceClient} from "../../../client/client" +import {RenameView} from "../views/renameView" import {StatusPanel} from "../../atom/components/statusPanel" export interface Dependencies { clearErrors() + getBuffer(filePath: string): Promise<{buffer: TextBuffer.ITextBuffer, isOpen: boolean}> getClient(filePath: string): Promise + renameView: RenameView statusPanel: StatusPanel } diff --git a/lib/main/atom/commands/renameRefactor.ts b/lib/main/atom/commands/renameRefactor.ts new file mode 100644 index 000000000..37fd05c6c --- /dev/null +++ b/lib/main/atom/commands/renameRefactor.ts @@ -0,0 +1,49 @@ +import {commands} from "./registry" +import {commandForTypeScript, getFilePathPosition} from "../atomUtils" +import {spanToRange} from "./../../utils/tsUtil" + +commands.set("typescript:rename-refactor", deps => { + return async e => { + if (!commandForTypeScript(e)) { + return + } + + const location = getFilePathPosition() + const client = await deps.getClient(location.file) + const {body: {info, locs}} = await client.executeRename(location) + + 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.getBuffer(loc.file) + buffer.transact(() => { + for (const span of loc.locs) { + buffer.setTextInRange(spanToRange(span), newName) + } + }) + if (!isOpen) { + buffer.save() + buffer.onDidSave(() => { + buffer.destroy() + }) + } + }) + } +}) diff --git a/lib/main/atom/views/renameView.ts b/lib/main/atom/views/renameView.ts index 4b66770f1..1517c8c0a 100644 --- a/lib/main/atom/views/renameView.ts +++ b/lib/main/atom/views/renameView.ts @@ -10,12 +10,10 @@ 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 @@ -23,7 +21,7 @@ export class RenameView private newNameEditor: EditorViewzz; private validationMessage: JQuery; - private fileCount: JQuery; + private panel: AtomCore.Panel; private title: JQuery; static content = html; @@ -62,21 +60,25 @@ export class RenameView }); } + public setPanel(panel: AtomCore.Panel) { + this.panel = panel + } + public editorAtRenameStart: AtomCore.IEditor = null; 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; } - 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) { @@ -89,16 +91,34 @@ export class RenameView 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(), 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/atomts.ts b/lib/main/atomts.ts index aa1140027..1010c3362 100644 --- a/lib/main/atomts.ts +++ b/lib/main/atomts.ts @@ -14,9 +14,10 @@ import {AutocompleteProvider} from './atom/autoCompleteProvider' // import * as fs from 'fs' import * as hyperclickProvider from "../hyperclickProvider" // import * as path from 'path' -import * as renameView from './atom/views/renameView' +import {attach as attachRenameView} from './atom/views/renameView' import * as tsconfig from "tsconfig/dist/tsconfig" import {flatten, values} from "lodash" +import * as Atom from "atom" // globals const subscriptions = new CompositeDisposable() @@ -42,6 +43,8 @@ export function activate(state: PackageState) { } } + // Add the rename view + const {renameView} = attachRenameView() const statusPanel = StatusPanel.create() statusBar.addRightTile({ @@ -66,23 +69,46 @@ export function activate(state: PackageState) { }) } - // Add the rename view - renameView.attach() - // Register the commands registerCommands({ clearErrors() { errorPusher.clear() }, - async getClient(filePath: string) { - for (const pane of panes) { - if (pane.filePath === filePath) { - return pane.client + async getBuffer(filePath: string) { + const pane = panes.find(pane => pane.filePath === filePath) + if (pane) { + return { + buffer: pane.editor.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, + isOpen: false + } + }, + async getClient(filePath: string) { + const pane = panes.find(pane => pane.filePath === filePath) + if (pane) { + return pane.client + } + return clientResolver.get(filePath) }, + renameView, statusPanel, }) diff --git a/lib/typings/atom.d.ts b/lib/typings/atom.d.ts index c6c2b0edb..29c8f1b6c 100644 --- a/lib/typings/atom.d.ts +++ b/lib/typings/atom.d.ts @@ -5,4 +5,11 @@ declare module "atom" { add(disposable: AtomCore.Disposable) dispose() } + + var TextBuffer: { + new (opts?: { + filePath?: string + load?: boolean + }): TextBuffer.ITextBuffer + } } diff --git a/lib/typings/atom_core.d.ts b/lib/typings/atom_core.d.ts index 526c21c66..c0d49fcb2 100644 --- a/lib/typings/atom_core.d.ts +++ b/lib/typings/atom_core.d.ts @@ -6,6 +6,8 @@ declare namespace AtomCore { declare namespace TextBuffer { interface ITextBuffer { - onDidChange(callback: Function): AtomCore.Disposable + onDidChange(callback: Function): AtomCore.Disposable + onDidReload(callback: Function): AtomCore.Disposable + onDidSave(callback: Function): AtomCore.Disposable } } 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'}, From 67167c80db3e0528d48259b64608a97658de37b5 Mon Sep 17 00:00:00 2001 From: Guntars Asmanis-Graham Date: Sat, 24 Dec 2016 21:16:08 -0500 Subject: [PATCH 41/70] Rename some files for consistency --- dist/main/atom/components/index.js | 2 +- dist/main/atom/components/{ts-view.js => tsView.js} | 0 dist/main/atomts.js | 8 ++++---- dist/main/{error_pusher.js => errorPusher.js} | 0 ...{typescript_editor_pane.js => typescriptEditorPane.js} | 0 lib/main/atom/components/index.ts | 2 +- lib/main/atom/components/{ts-view.ts => tsView.ts} | 0 lib/main/atomts.ts | 4 ++-- lib/main/{error_pusher.ts => errorPusher.ts} | 0 ...{typescript_editor_pane.ts => typescriptEditorPane.ts} | 0 10 files changed, 8 insertions(+), 8 deletions(-) rename dist/main/atom/components/{ts-view.js => tsView.js} (100%) rename dist/main/{error_pusher.js => errorPusher.js} (100%) rename dist/main/{typescript_editor_pane.js => typescriptEditorPane.js} (100%) rename lib/main/atom/components/{ts-view.ts => tsView.ts} (100%) rename lib/main/{error_pusher.ts => errorPusher.ts} (100%) rename lib/main/{typescript_editor_pane.ts => typescriptEditorPane.ts} (100%) diff --git a/dist/main/atom/components/index.js b/dist/main/atom/components/index.js index d2905b34c..1819bc7eb 100644 --- a/dist/main/atom/components/index.js +++ b/dist/main/atom/components/index.js @@ -2,4 +2,4 @@ function __export(m) { for (var p in m) if (!exports.hasOwnProperty(p)) exports[p] = m[p]; } -__export(require("./ts-view")); +__export(require("./tsView")); diff --git a/dist/main/atom/components/ts-view.js b/dist/main/atom/components/tsView.js similarity index 100% rename from dist/main/atom/components/ts-view.js rename to dist/main/atom/components/tsView.js diff --git a/dist/main/atomts.js b/dist/main/atomts.js index 837c2aa38..d85c3bb52 100644 --- a/dist/main/atomts.js +++ b/dist/main/atomts.js @@ -3,8 +3,8 @@ const tslib_1 = require("tslib"); const clientResolver_1 = require("../client/clientResolver"); const atom_1 = require("atom"); const lodash_1 = require("lodash"); -const error_pusher_1 = require("./error_pusher"); -const typescript_editor_pane_1 = require("./typescript_editor_pane"); +const errorPusher_1 = require("./errorPusher"); +const typescriptEditorPane_1 = require("./typescriptEditorPane"); const statusPanel_1 = require("./atom/components/statusPanel"); const atomConfig = require("./atom/atomConfig"); const autoCompleteProvider_1 = require("./atom/autoCompleteProvider"); @@ -35,7 +35,7 @@ function activate(state) { priority: statusPriority }); subscriptions.add(statusPanel); - const errorPusher = new error_pusher_1.ErrorPusher(); + const errorPusher = new errorPusher_1.ErrorPusher(); exports.clientResolver.on("pendingRequestsChange", () => { const pending = lodash_2.flatten(lodash_2.values(exports.clientResolver.clients).map(cl => cl.pending)); statusPanel.setPending(pending); @@ -96,7 +96,7 @@ function activate(state) { pane.client.executeGetErr({ files, delay: 100 }); }, 50); subscriptions.add(atom.workspace.observeTextEditors((editor) => { - panes.push(new typescript_editor_pane_1.TypescriptEditorPane(editor, { + panes.push(new typescriptEditorPane_1.TypescriptEditorPane(editor, { onDispose(pane) { if (activePane === pane) { activePane = null; diff --git a/dist/main/error_pusher.js b/dist/main/errorPusher.js similarity index 100% rename from dist/main/error_pusher.js rename to dist/main/errorPusher.js diff --git a/dist/main/typescript_editor_pane.js b/dist/main/typescriptEditorPane.js similarity index 100% rename from dist/main/typescript_editor_pane.js rename to dist/main/typescriptEditorPane.js diff --git a/lib/main/atom/components/index.ts b/lib/main/atom/components/index.ts index ec148a328..d51358481 100644 --- a/lib/main/atom/components/index.ts +++ b/lib/main/atom/components/index.ts @@ -1 +1 @@ -export * from "./ts-view"; +export * from "./tsView"; diff --git a/lib/main/atom/components/ts-view.ts b/lib/main/atom/components/tsView.ts similarity index 100% rename from lib/main/atom/components/ts-view.ts rename to lib/main/atom/components/tsView.ts diff --git a/lib/main/atomts.ts b/lib/main/atomts.ts index 1010c3362..3cce6dcd9 100644 --- a/lib/main/atomts.ts +++ b/lib/main/atomts.ts @@ -3,10 +3,10 @@ import {ClientResolver} from "../client/clientResolver" import {CompositeDisposable} from "atom" import {debounce} from "lodash" -import {ErrorPusher} from "./error_pusher" +import {ErrorPusher} from "./errorPusher" import {LinterRegistry, Linter} from "../typings/linter" import {StatusBar} from "../typings/status_bar" -import {TypescriptEditorPane} from "./typescript_editor_pane" +import {TypescriptEditorPane} from "./typescriptEditorPane" import {StatusPanel} from "./atom/components/statusPanel" import * as atomConfig from './atom/atomConfig' // import * as atomUtils from './atom/atomUtils' diff --git a/lib/main/error_pusher.ts b/lib/main/errorPusher.ts similarity index 100% rename from lib/main/error_pusher.ts rename to lib/main/errorPusher.ts diff --git a/lib/main/typescript_editor_pane.ts b/lib/main/typescriptEditorPane.ts similarity index 100% rename from lib/main/typescript_editor_pane.ts rename to lib/main/typescriptEditorPane.ts From 191990f5dc7d74db143f1d4546e647b8d004a525 Mon Sep 17 00:00:00 2001 From: Guntars Asmanis-Graham Date: Mon, 26 Dec 2016 23:18:21 -0500 Subject: [PATCH 42/70] Ensure changes right before saving are picked up --- dist/main/typescriptEditorPane.js | 61 ++++++++++++++++++------------- lib/main/typescriptEditorPane.ts | 28 +++++++++++++- package.json | 5 ++- 3 files changed, 66 insertions(+), 28 deletions(-) diff --git a/dist/main/typescriptEditorPane.js b/dist/main/typescriptEditorPane.js index 8b391abd3..94d97e3bc 100644 --- a/dist/main/typescriptEditorPane.js +++ b/dist/main/typescriptEditorPane.js @@ -13,6 +13,7 @@ class TypescriptEditorPane { this.isActive = false; this.isTSConfig = false; this.isTypescript = false; + this.stoppedChangingCallbacks = []; this.isOpen = false; this.occurrenceMarkers = []; this.subscriptions = new atom_1.CompositeDisposable(); @@ -71,40 +72,20 @@ class TypescriptEditorPane { }; this.onDidSave = (event) => tslib_1.__awaiter(this, void 0, void 0, function* () { if (this.filePath !== event.path) { - console.log("file path changed to", event.path); this.client = yield atomts_1.clientResolver.get(event.path); this.filePath = event.path; this.isTSConfig = path_1.basename(this.filePath) === "tsconfig.json"; } + if (this.changedAt && this.changedAt > (this.stoppedChangingAt | 0)) { + yield new Promise(resolve => this.stoppedChangingCallbacks.push(resolve)); + } if (this.opts.onSave) { this.opts.onSave(this); } - const result = yield this.client.executeCompileOnSaveAffectedFileList({ - file: this.filePath - }); - this.opts.statusPanel.setBuildStatus(null); - const fileNames = lodash_1.flatten(result.body.map(project => project.fileNames)); - if (fileNames.length === 0) { - return; - } - try { - const promises = fileNames.map(file => this.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 - }); - } + this.compileOnSave(); }); this.onDidStopChanging = ({ changes }) => { + this.stoppedChangingAt = Date.now(); if (this.isTypescript && this.filePath) { if (this.isOpen) { if (changes.length !== 0) { @@ -124,6 +105,8 @@ class TypescriptEditorPane { delay: 100 }); } + this.stoppedChangingCallbacks.forEach(fn => fn()); + this.stoppedChangingCallbacks.length = 0; }; this.editor = editor; this.filePath = editor.getPath(); @@ -180,6 +163,34 @@ class TypescriptEditorPane { marker.destroy(); } } + compileOnSave() { + return tslib_1.__awaiter(this, void 0, void 0, function* () { + const result = yield this.client.executeCompileOnSaveAffectedFileList({ + file: this.filePath + }); + this.opts.statusPanel.setBuildStatus(null); + const fileNames = lodash_1.flatten(result.body.map(project => project.fileNames)); + if (fileNames.length === 0) { + return; + } + try { + const promises = fileNames.map(file => this.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() { const editorView = atom_space_pen_views_1.$(atom.views.getView(this.editor)); tooltipManager.attach(editorView, this.editor); diff --git a/lib/main/typescriptEditorPane.ts b/lib/main/typescriptEditorPane.ts index c2d696c24..cd44e3727 100644 --- a/lib/main/typescriptEditorPane.ts +++ b/lib/main/typescriptEditorPane.ts @@ -22,15 +22,28 @@ interface PaneOptions { } export class TypescriptEditorPane implements AtomCore.Disposable { + // Timestamp for didChange event changedAt: number + + // Timestamp for activated event activeAt: number + client: TypescriptServiceClient + + // Path to the project's tsconfig.json configFile: string = "" + filePath: string isActive = false isTSConfig = false isTypescript = false + // Timestamp for last didStopChanging event + stoppedChangingAt: number + + // Callback that is going to be executed after the next didStopChanging event is processed + stoppedChangingCallbacks: Function[] = [] + private opts: PaneOptions private isOpen = false @@ -181,16 +194,24 @@ export class TypescriptEditorPane implements AtomCore.Disposable { onDidSave = async event => { if (this.filePath !== event.path) { - console.log("file path changed to", event.path) this.client = await clientResolver.get(event.path) this.filePath = event.path this.isTSConfig = basename(this.filePath) === "tsconfig.json" } + // Check if there isn't a onDidStopChanging event pending. If so, wait for it before updating + if (this.changedAt && this.changedAt > (this.stoppedChangingAt|0)) { + await new Promise(resolve => this.stoppedChangingCallbacks.push(resolve)) + } + if (this.opts.onSave) { this.opts.onSave(this) } + this.compileOnSave() + } + + async compileOnSave() { const result = await this.client.executeCompileOnSaveAffectedFileList({ file: this.filePath }) @@ -224,6 +245,8 @@ export class TypescriptEditorPane implements AtomCore.Disposable { } onDidStopChanging = ({changes}) => { + this.stoppedChangingAt = Date.now() + if (this.isTypescript && this.filePath) { if (this.isOpen) { @@ -254,6 +277,9 @@ export class TypescriptEditorPane implements AtomCore.Disposable { delay: 100 }) } + + this.stoppedChangingCallbacks.forEach(fn => fn()) + this.stoppedChangingCallbacks.length = 0 } setupTooltipView() { diff --git a/package.json b/package.json index aa2718267..4d18d66ac 100644 --- a/package.json +++ b/package.json @@ -8,8 +8,9 @@ "atom-typescript:grammar-used" ], "scripts": { - "build": "ts-node scripts/grammar.ts", - "test": "tsc -p ./lib && tsc --noEmit -p ./scripts" + "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", From bf05d066ddfc37a17947c7220bcc037784f624a4 Mon Sep 17 00:00:00 2001 From: Guntars Asmanis-Graham Date: Wed, 28 Dec 2016 16:35:36 -0500 Subject: [PATCH 43/70] Log tsserver output with console.warn --- dist/client/client.js | 4 +++- lib/client/client.ts | 5 ++++- 2 files changed, 7 insertions(+), 2 deletions(-) diff --git a/dist/client/client.js b/dist/client/client.js index d8bf9cdf0..846c3e053 100644 --- a/dist/client/client.js +++ b/dist/client/client.js @@ -7,6 +7,7 @@ class TypescriptServiceClient { this.callbacks = {}; this.listeners = {}; this.seq = 0; + this.tsServerArgs = []; this.onMessage = (res) => { if (isResponse(res)) { const callback = this.callbacks[res.request_seq]; @@ -136,7 +137,7 @@ class TypescriptServiceClient { if (!this.serverPromise) { this.serverPromise = new Promise((resolve, reject) => { console.log("starting", this.tsServerPath); - const cp = child_process_1.spawn(this.tsServerPath, []); + const cp = child_process_1.spawn(this.tsServerPath, this.tsServerArgs); cp.once("error", err => { console.log("tsserver starting failed with", err); reject(err); @@ -146,6 +147,7 @@ class TypescriptServiceClient { reject({ code }); }); messageStream(cp.stdout).on("data", this.onMessage); + cp.stderr.on("data", data => console.warn("tsserver stderr:", data.toString())); this.sendRequest(cp, "ping", null, true).then(res => resolve(cp), err => resolve(cp)); }); return this.serverPromise.catch(error => { diff --git a/lib/client/client.ts b/lib/client/client.ts index f4f3e376a..9bf13cbe7 100644 --- a/lib/client/client.ts +++ b/lib/client/client.ts @@ -29,6 +29,7 @@ export class TypescriptServiceClient { /** Path to the tsserver executable */ readonly tsServerPath: string + readonly tsServerArgs = [] readonly version: string constructor(tsServerPath: string, version) { @@ -199,7 +200,7 @@ export class TypescriptServiceClient { this.serverPromise = new Promise((resolve, reject) => { console.log("starting", this.tsServerPath) - const cp = spawn(this.tsServerPath, []) + const cp = spawn(this.tsServerPath, this.tsServerArgs) cp.once("error", err => { console.log("tsserver starting failed with", err) @@ -213,6 +214,8 @@ export class TypescriptServiceClient { messageStream(cp.stdout).on("data", this.onMessage) + cp.stderr.on("data", data => console.warn("tsserver stderr:", 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)) }) From 2138ef84bbc10fa9e53b02580875051a71b01de6 Mon Sep 17 00:00:00 2001 From: Guntars Asmanis-Graham Date: Wed, 28 Dec 2016 16:40:14 -0500 Subject: [PATCH 44/70] Use a nightly Typescript to fix the line ending issue --- package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/package.json b/package.json index 4d18d66ac..0f81ecbbb 100644 --- a/package.json +++ b/package.json @@ -70,7 +70,7 @@ "resolve": "1.1.7", "tsconfig": "^2.2.0", "tslib": "1.2.0", - "typescript": "2.1.4" + "typescript": "2.2.0-dev.20161228" }, "devDependencies": { "@types/cson": "0.0.30", From 7522bcdd6fa6d5cc8882681e219ce01344bddff8 Mon Sep 17 00:00:00 2001 From: Guntars Asmanis-Graham Date: Wed, 28 Dec 2016 17:35:01 -0500 Subject: [PATCH 45/70] Format tsconfig.json and update some config vars --- dist/client/client.js | 34 ++--- dist/client/clientResolver.js | 16 ++- dist/client/findServer.js | 2 + dist/hyperclickProvider.js | 13 ++ dist/main/atom/atomConfig.js | 4 + dist/main/atom/atomUtils.js | 28 ++++- dist/main/atom/autoCompleteProvider.js | 22 ++++ dist/main/atom/commands/checkAllFiles.js | 4 + dist/main/atom/commands/index.js | 119 ++++++++++++++++++ dist/main/atom/commands/registry.js | 3 + dist/main/atom/components/tsView.js | 9 +- dist/main/atom/fileStatusCache.js | 4 + dist/main/atom/gotoHistory.js | 14 +++ dist/main/atom/tooltipManager.js | 11 +- dist/main/atom/views/fileSymbolsView.js | 5 + dist/main/atom/views/mainPanelView.js | 40 +++++- dist/main/atom/views/projectSymbolsView.js | 5 + dist/main/atom/views/renameView.js | 1 + .../atom/views/simpleOverlaySelectionView.js | 12 ++ dist/main/atom/views/simpleSelectionView.js | 11 ++ dist/main/atom/views/tooltipView.js | 2 + dist/main/atomts.js | 12 ++ dist/main/errorPusher.js | 3 + dist/main/lang/utils.js | 63 ++++++++++ dist/main/tsconfig/formatting.js | 7 ++ dist/main/typescriptEditorPane.js | 6 + dist/main/utils/fsUtil.js | 14 +++ lib/client/client.ts | 42 ++++--- lib/client/clientResolver.ts | 14 ++- lib/main/atom/atomUtils.ts | 4 +- lib/main/atom/commands/registry.ts | 2 +- lib/main/atom/views/semanticViewGlobals.d.ts | 5 - lib/tsconfig.json | 40 +++--- lib/typings/atom_core.d.ts | 4 + 34 files changed, 497 insertions(+), 78 deletions(-) delete mode 100644 lib/main/atom/views/semanticViewGlobals.d.ts diff --git a/dist/client/client.js b/dist/client/client.js index 846c3e053..f7cc09e35 100644 --- a/dist/client/client.js +++ b/dist/client/client.js @@ -2,8 +2,22 @@ const child_process_1 = require("child_process"); const stream_1 = require("stream"); const byline = require("byline"); +exports.CommandWithResponse = new Set([ + "compileOnSaveAffectedFileList", + "compileOnSaveEmitFile", + "completionEntryDetails", + "completions", + "definition", + "occurrences", + "projectInfo", + "quickinfo", + "references", + "reload", + "rename", +]); class TypescriptServiceClient { constructor(tsServerPath, version) { + /** Map of callbacks that are waiting for responses */ this.callbacks = {}; this.listeners = {}; this.seq = 0; @@ -84,8 +98,7 @@ class TypescriptServiceClient { } execute(command, args) { return this.serverPromise.then(cp => { - const expectResponse = !!TypescriptServiceClient.commandWithResponse[command]; - return this.sendRequest(cp, command, args, expectResponse); + return this.sendRequest(cp, command, args, exports.CommandWithResponse.has(command)); }).catch(err => { console.log("command", command, "failed due to", err); throw err; @@ -148,10 +161,11 @@ class TypescriptServiceClient { }); messageStream(cp.stdout).on("data", this.onMessage); cp.stderr.on("data", data => console.warn("tsserver stderr:", 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)); }); return this.serverPromise.catch(error => { - this.serverPromise = null; + this.serverPromise = undefined; throw error; }); } @@ -160,19 +174,6 @@ class TypescriptServiceClient { } } } -TypescriptServiceClient.commandWithResponse = { - compileOnSaveAffectedFileList: true, - compileOnSaveEmitFile: true, - completionEntryDetails: true, - completions: true, - definition: true, - occurrences: true, - projectInfo: true, - quickinfo: true, - references: true, - reload: true, - rename: true, -}; exports.TypescriptServiceClient = TypescriptServiceClient; function isEvent(res) { return res.type === "event"; @@ -183,6 +184,7 @@ function isResponse(res) { 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 }); diff --git a/dist/client/clientResolver.js b/dist/client/clientResolver.js index 99d79e2d4..c5a713654 100644 --- a/dist/client/clientResolver.js +++ b/dist/client/clientResolver.js @@ -7,6 +7,10 @@ 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); @@ -22,10 +26,7 @@ class ClientResolver extends events.EventEmitter { if (this.clients[serverPath]) { return this.clients[serverPath].client; } - const entry = this.clients[serverPath] = { - client: new client_1.TypescriptServiceClient(serverPath, version), - pending: [], - }; + const entry = this.addClient(serverPath, new client_1.TypescriptServiceClient(serverPath, version)); entry.client.startServer(); entry.client.on("pendingRequestsChange", pending => { entry.pending = pending; @@ -45,6 +46,13 @@ class ClientResolver extends events.EventEmitter { return entry.client; }); } + addClient(serverPath, client) { + this.clients[serverPath] = { + client, + pending: [], + }; + return this.clients[serverPath]; + } } exports.ClientResolver = ClientResolver; function resolveServer(sourcePath) { diff --git a/dist/client/findServer.js b/dist/client/findServer.js index 7124aa422..602c92b84 100644 --- a/dist/client/findServer.js +++ b/dist/client/findServer.js @@ -1,6 +1,7 @@ "use strict"; const fs = require("fs"); const path = require("path"); +/** Recursively search all directories rooted at the argument and find all typescript modules */ function findTypescriptServers(root) { const results = []; if (!path.isAbsolute(root)) { @@ -44,6 +45,7 @@ function findTypescriptServers(root) { } } exports.findTypescriptServers = findTypescriptServers; +/** Get info about the tsserver at the prefix */ function getServerInfo(prefix, callback) { const tsDir = path.join(prefix, "node_modules", "typescript"); fs.readFile(path.join(tsDir, "package.json"), "utf8", (err, pkg) => { diff --git a/dist/hyperclickProvider.js b/dist/hyperclickProvider.js index 16c66f2af..b5d568c91 100644 --- a/dist/hyperclickProvider.js +++ b/dist/hyperclickProvider.js @@ -9,6 +9,19 @@ function getSuggestionForWord(textEditor, text, range) { 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/dist/main/atom/atomConfig.js b/dist/main/atom/atomConfig.js index 3335e2c9f..48ffaa5c9 100644 --- a/dist/main/atom/atomConfig.js +++ b/dist/main/atom/atomConfig.js @@ -1,5 +1,9 @@ "use strict"; const utils_1 = require("../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) { return atom.config.get(packageName + '.' + utils_1.getName(nameLambda)); diff --git a/dist/main/atom/atomUtils.js b/dist/main/atom/atomUtils.js index 5fa3bb6a9..807d713b0 100644 --- a/dist/main/atom/atomUtils.js +++ b/dist/main/atom/atomUtils.js @@ -5,6 +5,7 @@ const fs = require("fs"); const fsu = require("../utils/fsUtil"); const _atom = require("atom"); const url = require("url"); +// Return line/offset position in the editor using 1-indexed coordinates function getEditorPosition(editor) { const pos = editor.getCursorBufferPosition(); return { @@ -38,6 +39,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(); @@ -75,10 +77,11 @@ function getEditorsForAllPaths(filePaths) { map[fsu.consistentPath(editor.getPath())] = editor; } activeEditors.forEach(addConsistentlyToMap); + /// 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(p => atom.workspace.open(p, {})); + 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; @@ -92,6 +95,7 @@ function getRangeForTextSpan(editor, ts) { 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(editor => !!editor.getPath()) @@ -136,7 +140,11 @@ 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'; @@ -161,6 +169,7 @@ function kindToType(kind) { } } exports.kindToType = kindToType; +/** Utility functions for commands */ function commandForTypeScript(e) { var editor = atom.workspace.getActiveTextEditor(); if (!editor) @@ -171,6 +180,7 @@ 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()); @@ -191,14 +201,21 @@ function editorInTheseScopes(matches) { 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, (e) => { if (!commandForTypeScript(e)) @@ -225,14 +242,23 @@ 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); + // Sample: + // atom.project.relativize(`D:/REPOS/atom-typescript/lib/main/atom/atomUtils.ts`) return '~' + atom.project.relativize(filePath); } exports.getFilePathRelativeToAtomProject = getFilePathRelativeToAtomProject; +/** + * Opens the given file in the same project + */ function openFile(filePath, position = {}) { var config = {}; if (position.line) { diff --git a/dist/main/atom/autoCompleteProvider.js b/dist/main/atom/autoCompleteProvider.js index e26573394..00c143f60 100644 --- a/dist/main/atom/autoCompleteProvider.js +++ b/dist/main/atom/autoCompleteProvider.js @@ -11,8 +11,22 @@ class AutocompleteProvider { this.excludeLowerPriority = false; this.clientResolver = clientResolver; } + // Try to reuse the last completions we got from tsserver if they're for the same position. getSuggestionsWithCache(prefix, location) { return tslib_1.__awaiter(this, void 0, void 0, function* () { + // NOTE: While typing this can get out of sync with what tsserver would return so find a better + // way to reuse the completions. + // if (this.lastSuggestions) { + // 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(tslib_1.__assign({ prefix }, location)); const suggestions = completions.body.map(entry => ({ @@ -47,6 +61,7 @@ class AutocompleteProvider { if (alphaPrefix !== "") { suggestions = fuzzaldrin.filter(suggestions, alphaPrefix, { key: "text" }); } + // Get additional details for the first few suggestions, but don't wait for it to complete this.getAdditionalDetails(suggestions.slice(0, 15), location); const trimmed = prefix.trim(); return suggestions.map(suggestion => (tslib_1.__assign({ replacementPrefix: getReplacementPrefix(prefix, trimmed, suggestion.text) }, suggestion))); @@ -69,6 +84,7 @@ class AutocompleteProvider { } } 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 ""; @@ -80,6 +96,12 @@ function getReplacementPrefix(prefix, trimmed, replacement) { 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) { return { file: opts.editor.getPath(), diff --git a/dist/main/atom/commands/checkAllFiles.js b/dist/main/atom/commands/checkAllFiles.js index e3d4264ed..dcf5f2420 100644 --- a/dist/main/atom/commands/checkAllFiles.js +++ b/dist/main/atom/commands/checkAllFiles.js @@ -15,6 +15,10 @@ registry_1.commands.set("typescript:check-all-files", deps => { }); 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); diff --git a/dist/main/atom/commands/index.js b/dist/main/atom/commands/index.js index 10245abe6..9b6e92243 100644 --- a/dist/main/atom/commands/index.js +++ b/dist/main/atom/commands/index.js @@ -1,5 +1,18 @@ +// import atomUtils = require("../atomUtils"); +// import path = require('path'); +// import renameView = require("../views/renameView"); +// 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 {simpleSelectionView} from "../views/simpleSelectionView"; +// import escapeHtml = require('escape-html'); "use strict"; +// Load all the web components +// export * from "../components/componentRegistry"; const registry_1 = require("./registry"); +// Import all of the command files for their side effects require("./build"); require("./checkAllFiles"); require("./clearErrors"); @@ -10,8 +23,114 @@ function registerCommands(deps) { for (const [name, command] of registry_1.commands) { atom.commands.add("atom-workspace", name, command(deps)); } + // 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: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}`); + // } + // }); + // }); + // 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 = cursor.getBufferPosition() + // var filePath = editor.getPath(); + // + // clientResolver.get(filePath).then(client => { + // return client.executeQuickInfo({ + // file: filePath, + // line: position.row+1, + // offset: position.column+1 + // }).then(({body: {displayString, documentation}}) => { + // var decoration = editor.decorateMarker(cursor.getMarker(), { + // type: 'overlay', + // item: createTypeOverlay(displayString, documentation) + // }); + // + // 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); + // }).catch(() => { /* ignore errors */ }) + // }) + // }); + // + // atom.commands.add('atom-workspace', 'typescript:go-to-next', (e) => { + // gotoHistory.gotoNext(); + // }); + // atom.commands.add('atom-workspace', 'typescript:go-to-previous', (e) => { + // gotoHistory.gotoPrevious(); + // }); + // 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('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('atom-workspace', 'typescript:sync', (e) => { console.log("typescript:sync trigerred"); + // if (!atomUtils.commandForTypeScript(e)) return; + // panelView.softReset(); }); } exports.registerCommands = registerCommands; diff --git a/dist/main/atom/commands/registry.js b/dist/main/atom/commands/registry.js index 0ba219db8..ea2350e74 100644 --- a/dist/main/atom/commands/registry.js +++ b/dist/main/atom/commands/registry.js @@ -1,2 +1,5 @@ "use strict"; +// 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(); diff --git a/dist/main/atom/components/tsView.js b/dist/main/atom/components/tsView.js index 4b6b2d9fe..f7105537d 100644 --- a/dist/main/atom/components/tsView.js +++ b/dist/main/atom/components/tsView.js @@ -1,19 +1,24 @@ +// Some docs +// http://www.html5rocks.com/en/tutorials/webcomponents/customelements/ (look at lifecycle callback methods) "use strict"; 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); } + // API text(text) { this.editor.setText(text); } diff --git a/dist/main/atom/fileStatusCache.js b/dist/main/atom/fileStatusCache.js index 03d3bcab1..3a18a94b2 100644 --- a/dist/main/atom/fileStatusCache.js +++ b/dist/main/atom/fileStatusCache.js @@ -1,4 +1,8 @@ "use strict"; +/** + * We keep an in memory cache of certain knowledge points regarding a few file paths + * This file maintains that + */ const fsUtil_1 = require("../utils/fsUtil"); ; let fileStatuses = {}; diff --git a/dist/main/atom/gotoHistory.js b/dist/main/atom/gotoHistory.js index 03201b11f..d3f5566c8 100644 --- a/dist/main/atom/gotoHistory.js +++ b/dist/main/atom/gotoHistory.js @@ -2,6 +2,7 @@ exports.errorsInOpenFiles = { members: [] }; exports.buildOutput = { members: [] }; exports.referencesOutput = { members: [] }; +/** This *must* always be set */ exports.activeList = exports.errorsInOpenFiles; function gotoLine(filePath, line, col, list) { var activeFile, activeEditor = atom.workspace.getActiveTextEditor(); @@ -20,25 +21,34 @@ function gotoLine(filePath, line, col, list) { list.lastPosition = { filePath, line, col }; } exports.gotoLine = gotoLine; +/** + * 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() { + // Early exit if no members if (!exports.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 (!exports.activeList.lastPosition) return 0; var lastPosition = exports.activeList.lastPosition; var index = indexOf(exports.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 */ function gotoNext() { var currentIndex = findCurrentIndexInList(); if (currentIndex == -1) return; var nextIndex = currentIndex + 1; + // If next is == length then loop to zero if (nextIndex == exports.activeList.members.length) { nextIndex = 0; } @@ -51,6 +61,7 @@ function gotoPrevious() { if (currentIndex == -1) return; var previousIndex = currentIndex - 1; + // If next is == -1 then loop to length if (previousIndex == -1) { previousIndex = exports.activeList.members.length - 1; } @@ -58,6 +69,9 @@ function gotoPrevious() { gotoLine(previous.filePath, previous.line, previous.col, exports.activeList); } exports.gotoPrevious = gotoPrevious; +/** + * Utility Return index of element in an array + */ function indexOf(items, filter) { for (var i = 0; i < items.length; i++) { if (filter(items[i])) { diff --git a/dist/main/atom/tooltipManager.js b/dist/main/atom/tooltipManager.js index fc8076071..79b6dc0a6 100644 --- a/dist/main/atom/tooltipManager.js +++ b/dist/main/atom/tooltipManager.js @@ -1,5 +1,7 @@ +// Inspiration : https://atom.io/packages/ide-haskell +// and https://atom.io/packages/ide-flow "use strict"; -const atomUtils = require("./atomUtils"); +const atomUtils = require("./atomUtils"); ///ts:import:generated const atomts_1 = require("../atomts"); const path = require("path"); const fs = require("fs"); @@ -17,11 +19,13 @@ function getFromShadowDom(element, selector) { exports.getFromShadowDom = getFromShadowDom; function attach(editorView, editor) { var rawView = editorView[0]; + // Only on ".ts" files var filePath = editor.getPath(); 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; } @@ -30,6 +34,7 @@ function attach(editorView, editor) { var subscriber = new Subscriber(); var exprTypeTimeout = null; var exprTypeTooltip = null; + // to debounce mousemove event's firing for some reason on some machines var lastExprTypeBufferPt; subscriber.subscribe(scroll, 'mousemove', (e) => { var pixelPt = pixelPositionFromMouseEvent(editorView, e); @@ -43,8 +48,10 @@ function attach(editorView, editor) { }); subscriber.subscribe(scroll, 'mouseout', (e) => clearExprTypeTimeout()); subscriber.subscribe(scroll, 'keydown', (e) => clearExprTypeTimeout()); + // Setup for clearing editor.onDidDestroy(() => deactivate()); function showExpressionType(e) { + // If we are already showing we should wait for that to clear if (exprTypeTooltip) return; var pixelPt = pixelPositionFromMouseEvent(editorView, e); @@ -56,6 +63,7 @@ function attach(editorView, editor) { 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, @@ -82,6 +90,7 @@ function attach(editorView, editor) { subscriber.unsubscribe(); clearExprTypeTimeout(); } + /** clears the timeout && the tooltip */ function clearExprTypeTimeout() { if (exprTypeTimeout) { clearTimeout(exprTypeTimeout); diff --git a/dist/main/atom/views/fileSymbolsView.js b/dist/main/atom/views/fileSymbolsView.js index 4d6bd10e7..bc6c6fd8d 100644 --- a/dist/main/atom/views/fileSymbolsView.js +++ b/dist/main/atom/views/fileSymbolsView.js @@ -1,6 +1,9 @@ "use strict"; const sp = require("atom-space-pen-views"); const atomUtils = require("../atomUtils"); +/** + * https://github.com/atom/atom-space-pen-views + */ class FileSymbolsView extends sp.SelectListView { constructor() { super(...arguments); @@ -14,6 +17,7 @@ class FileSymbolsView extends sp.SelectListView { this.filePath = filePath; super.setItems(items); } + /** override */ viewForItem(item) { return `
  • @@ -23,6 +27,7 @@ class FileSymbolsView extends sp.SelectListView {
  • `; } + /** override */ confirmed(item) { atom.workspace.open(this.filePath, { initialLine: item.position.line, diff --git a/dist/main/atom/views/mainPanelView.js b/dist/main/atom/views/mainPanelView.js index e6839da09..bb159dca4 100644 --- a/dist/main/atom/views/mainPanelView.js +++ b/dist/main/atom/views/mainPanelView.js @@ -49,7 +49,7 @@ class MainPanelView extends view.View { }); this.span({ class: 'layout horizontal atomts-panel-header', - style: 'align-items: center; flex: 1 1 auto; line-height: 24px;' + 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;', @@ -130,6 +130,19 @@ class MainPanelView extends view.View { } softReset() { console.log("soft reset"); + // 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)); + // } } setTsconfigInUse(tsconfigFilePath) { this.fullTsconfigPath = tsconfigFilePath; @@ -150,8 +163,25 @@ class MainPanelView extends view.View { atomUtils.openFile(this.fullTsconfigPath); } } + ///////////// Change JS File Status updateFileStatus(filePath) { + // 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('
    - ')); } @@ -221,7 +251,9 @@ class MainPanelView extends view.View { this.expanded = !this.expanded; this.setActivePanel(); } + ////////////// REFERENCES setReferences(references) { + // Select it this.referencesPanelSelected(true); this.referencesBody.empty(); if (references.length == 0) { @@ -244,9 +276,11 @@ class MainPanelView extends view.View { 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 }); } } + ///////////////////// BUILD setBuildPanelCount(errorCount, inProgressBuild = false) { var titleMain = inProgressBuild ? "Build Progress" : panelHeaders.build; var title = `${titleMain} ( No Errors )`; @@ -269,12 +303,15 @@ class MainPanelView extends view.View { this.buildBody.append(view.$); } setBuildProgress(progress) { + // 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; @@ -296,6 +333,7 @@ class MainPanelView extends view.View { 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 }); }); } diff --git a/dist/main/atom/views/projectSymbolsView.js b/dist/main/atom/views/projectSymbolsView.js index fa1ca8786..d2c82c4eb 100644 --- a/dist/main/atom/views/projectSymbolsView.js +++ b/dist/main/atom/views/projectSymbolsView.js @@ -1,6 +1,9 @@ "use strict"; const sp = require("atom-space-pen-views"); const atomUtils = require("../atomUtils"); +/** + * https://github.com/atom/atom-space-pen-views + */ class ProjectSymbolsView extends sp.SelectListView { constructor() { super(...arguments); @@ -20,6 +23,7 @@ class ProjectSymbolsView extends sp.SelectListView { var items = tsItems; super.setItems(items); } + /** override */ viewForItem(item) { return `
  • @@ -29,6 +33,7 @@ class ProjectSymbolsView extends sp.SelectListView {
  • `; } + /** override */ confirmed(item) { atom.workspace.open(item.filePath, { initialLine: item.position.line, diff --git a/dist/main/atom/views/renameView.js b/dist/main/atom/views/renameView.js index 52502f68c..dc69f5550 100644 --- a/dist/main/atom/views/renameView.js +++ b/dist/main/atom/views/renameView.js @@ -67,6 +67,7 @@ class RenameView extends view.View { this.newNameEditor.focus(); this.validationMessage.hide(); } + // Show the dialog and resolve the promise with the entered string showRenameDialog(options) { return new Promise((resolve, reject) => { this.renameThis(tslib_1.__assign({}, options, { onCancel: reject, onCommit: resolve })); diff --git a/dist/main/atom/views/simpleOverlaySelectionView.js b/dist/main/atom/views/simpleOverlaySelectionView.js index 598fb93d8..f54a4e050 100644 --- a/dist/main/atom/views/simpleOverlaySelectionView.js +++ b/dist/main/atom/views/simpleOverlaySelectionView.js @@ -1,3 +1,7 @@ +/** + * A functional form of the SelectListView + * Only one of these bad boys is allowed on the screen at one time + */ "use strict"; var singleton; function default_1(options, editor) { @@ -13,6 +17,9 @@ function default_1(options, editor) { } Object.defineProperty(exports, "__esModule", { value: true }); exports.default = default_1; +/** + * Various Utility section + */ const sp = require("atom-space-pen-views"); class SimpleOverlaySelectListView extends sp.SelectListView { constructor(options, editor) { @@ -28,21 +35,26 @@ class SimpleOverlaySelectListView extends sp.SelectListView { setItems() { super.setItems(this.options.items); } + /** override */ viewForItem(item) { return `
  • ${this.options.viewForItem(item)}
  • `; } + /** override */ confirmed(item) { 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() { diff --git a/dist/main/atom/views/simpleSelectionView.js b/dist/main/atom/views/simpleSelectionView.js index 4b5fb1daf..906da8c61 100644 --- a/dist/main/atom/views/simpleSelectionView.js +++ b/dist/main/atom/views/simpleSelectionView.js @@ -1,3 +1,7 @@ +/** + * A functional form of the SelectListView + * Only one of these bad boys is allowed on the screen at one time + */ "use strict"; var singleton; function simpleSelectionView(options) { @@ -11,6 +15,9 @@ function simpleSelectionView(options) { return singleton; } exports.simpleSelectionView = simpleSelectionView; +/** + * Various Utility section + */ const sp = require("atom-space-pen-views"); var $ = sp.$; class SimpleSelectListView extends sp.SelectListView { @@ -25,6 +32,7 @@ class SimpleSelectListView extends sp.SelectListView { setItems() { super.setItems(this.options.items); } + /** override */ viewForItem(item) { var view = this.options.viewForItem(item); if (typeof view === "string") { @@ -37,10 +45,12 @@ class SimpleSelectListView extends sp.SelectListView { } ; } + /** override */ confirmed(item) { this.options.confirmed(item); this.hide(); } + /** override */ getFilterKey() { return this.options.filterKey; } @@ -50,6 +60,7 @@ class SimpleSelectListView extends sp.SelectListView { this.panel = atom.workspace.addModalPanel({ item: this }); this.panel.show(); this.focusFilterEditor(); + // debugger; // DEBUG: the UI in the inspector so that it doesn't change on you } hide() { this.panel.hide(); diff --git a/dist/main/atom/views/tooltipView.js b/dist/main/atom/views/tooltipView.js index eaf8f779e..d6a906878 100644 --- a/dist/main/atom/views/tooltipView.js +++ b/dist/main/atom/views/tooltipView.js @@ -23,6 +23,7 @@ class TooltipView extends view.View { 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) { @@ -30,6 +31,7 @@ class TooltipView extends view.View { left = offset; right = offset; } + // Y axis adjust if (top + this.$[0].offsetHeight >= $(document.body).height()) { top = this.rect.top - this.$[0].offsetHeight; } diff --git a/dist/main/atomts.js b/dist/main/atomts.js index d85c3bb52..3d1f9fa15 100644 --- a/dist/main/atomts.js +++ b/dist/main/atomts.js @@ -1,5 +1,7 @@ "use strict"; const tslib_1 = require("tslib"); +// import {getFileStatus} from "./atom/fileStatusCache" +// import {$} from "atom-space-pen-views" const clientResolver_1 = require("../client/clientResolver"); const atom_1 = require("atom"); const lodash_1 = require("lodash"); @@ -7,15 +9,20 @@ const errorPusher_1 = require("./errorPusher"); const typescriptEditorPane_1 = require("./typescriptEditorPane"); const statusPanel_1 = require("./atom/components/statusPanel"); const atomConfig = require("./atom/atomConfig"); +// import * as atomUtils from './atom/atomUtils' const autoCompleteProvider_1 = require("./atom/autoCompleteProvider"); +// import * as fs from 'fs' const hyperclickProvider = require("../hyperclickProvider"); +// import * as path from 'path' const renameView_1 = require("./atom/views/renameView"); const tsconfig = require("tsconfig/dist/tsconfig"); const lodash_2 = require("lodash"); const Atom = require("atom"); +// globals const subscriptions = new atom_1.CompositeDisposable(); exports.clientResolver = new clientResolver_1.ClientResolver(); exports.config = atomConfig.schema; +// Register all custom components require("./atom/components"); const commands_1 = require("./atom/commands"); let linter; @@ -28,6 +35,7 @@ function activate(state) { statusPriority = panel.getPriority() - 1; } } + // Add the rename view const { renameView } = renameView_1.attach(); const statusPanel = statusPanel_1.StatusPanel.create(); statusBar.addRightTile({ @@ -46,6 +54,7 @@ function activate(state) { errorPusher.setErrors(type, filePath, diagnostics); }); } + // Register the commands commands_1.registerCommands({ clearErrors() { errorPusher.clear(); @@ -59,6 +68,7 @@ function activate(state) { isOpen: true }; } + // Wait for the buffer to load before resolving the promise const buffer = yield new Promise(resolve => { const buffer = new Atom.TextBuffer({ filePath, @@ -102,6 +112,7 @@ function activate(state) { activePane = null; } panes.splice(panes.indexOf(pane), 1); + // Clear errors if any from this pane errorPusher.setErrors("syntaxDiag", pane.filePath, []); errorPusher.setErrors("semanticDiag", pane.filePath, []); }, @@ -149,6 +160,7 @@ function consumeStatusBar(_statusBar) { statusBar = _statusBar; } exports.consumeStatusBar = consumeStatusBar; +// Registering an autocomplete provider function provide() { return [ new autoCompleteProvider_1.AutocompleteProvider(exports.clientResolver), diff --git a/dist/main/errorPusher.js b/dist/main/errorPusher.js index 90aba8f77..202529321 100644 --- a/dist/main/errorPusher.js +++ b/dist/main/errorPusher.js @@ -1,6 +1,7 @@ "use strict"; const lodash_1 = require("lodash"); const tsUtil_1 = require("./utils/tsUtil"); +/** Class that collects errors from all of the clients and pushes them to the Linter service */ class ErrorPusher { constructor() { this.errors = new Map(); @@ -23,6 +24,7 @@ class ErrorPusher { } }, 100); } + /** Set errors. Previous errors with the same prefix and filePath are going to be replaced */ setErrors(prefix, filePath, errors) { let prefixed = this.errors.get(prefix); if (!prefixed) { @@ -32,6 +34,7 @@ class ErrorPusher { prefixed.set(filePath, errors); this.pushErrors(); } + /** Clear all errors */ clear() { if (this.linter) { this.linter.deleteMessages(); diff --git a/dist/main/lang/utils.js b/dist/main/lang/utils.js index 1ca897637..a3b3d9d09 100644 --- a/dist/main/lang/utils.js +++ b/dist/main/lang/utils.js @@ -1,3 +1,16 @@ +// 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'; const path = require("path"); function mapValues(map) { @@ -7,6 +20,11 @@ function mapValues(map) { }, []); } exports.mapValues = mapValues; +/** + * 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((target, key) => { @@ -16,10 +34,17 @@ function assign(target, ...items) { }, 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((result, key) => { result[key] = true; @@ -27,6 +52,9 @@ function createMap(arr) { }, {}); } 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]); @@ -35,9 +63,21 @@ function pathResolve(from, to) { exports.pathResolve = pathResolve; class Signal { constructor() { + /** + * list of listeners that have been suscribed to this signal + */ this.listeners = []; + /** + * Priorities corresponding to the listeners + */ this.priorities = []; } + /** + * 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, priority = 0) { var index = this.listeners.indexOf(listener); if (index !== -1) { @@ -54,6 +94,11 @@ class Signal { this.priorities.push(priority); this.listeners.push(listener); } + /** + * unsubscribe a listener for the signal + * + * @params listener the previously subscribed listener + */ remove(listener) { var index = this.listeners.indexOf(listener); if (index >= 0) { @@ -61,6 +106,11 @@ class Signal { this.listeners.splice(index, 1); } } + /** + * dispatch an event + * + * @params parameter the parameter attached to the event dispatching + */ dispatch(parameter) { var hasBeenCanceled = this.listeners.every((listener) => { var result = listener(parameter); @@ -68,10 +118,16 @@ class Signal { }); return hasBeenCanceled; } + /** + * Remove all listener from the signal + */ clear() { this.listeners = []; this.priorities = []; } + /** + * @return true if the listener has been subsribed to this signal + */ hasListeners() { return this.listeners.length > 0; } @@ -96,6 +152,7 @@ function binarySearch(array, value) { return ~low; } exports.binarySearch = binarySearch; +// Not optimized function selectMany(arr) { var result = []; for (var i = 0; i < arr.length; i++) { @@ -106,12 +163,14 @@ function selectMany(arr) { return result; } exports.selectMany = selectMany; +// Not particularly awesome e.g. '/..foo' will pass function pathIsRelative(str) { if (!str.length) return false; return str[0] == '.' || str.substring(0, 2) == "./" || str.substring(0, 3) == "../"; } exports.pathIsRelative = pathIsRelative; +/** Key is string. Note: this data structure might have been a bad idea. Sorry. */ class Dict { constructor() { this.table = Object.create(null); @@ -134,12 +193,14 @@ class Dict { } } exports.Dict = Dict; +/** for testing ui lags only */ function delay(seconds = 2) { delayMilliseconds(seconds * 1000); } exports.delay = delay; ; function delayMilliseconds(milliseconds = 100) { + // Delay the thread var d1 = new Date(); var d2 = new Date(); while (d2.valueOf() < d1.valueOf() + milliseconds) { @@ -185,6 +246,7 @@ exports.debounce = debounce; var punctuations = createMap([';', '{', '}', '(', ')', '.', ':', '<', '>', "'", '"']); exports.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 */ function getName(nameLambda) { var m = nameExtractorRegex.exec(nameLambda + ""); if (m == null) @@ -193,6 +255,7 @@ 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); diff --git a/dist/main/tsconfig/formatting.js b/dist/main/tsconfig/formatting.js index 85c9afd68..ec5df09de 100644 --- a/dist/main/tsconfig/formatting.js +++ b/dist/main/tsconfig/formatting.js @@ -1,4 +1,11 @@ "use strict"; +/** + * 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 { diff --git a/dist/main/typescriptEditorPane.js b/dist/main/typescriptEditorPane.js index 94d97e3bc..397b70692 100644 --- a/dist/main/typescriptEditorPane.js +++ b/dist/main/typescriptEditorPane.js @@ -9,10 +9,12 @@ const tsUtil_1 = require("./utils/tsUtil"); const tooltipManager = require("./atom/tooltipManager"); class TypescriptEditorPane { constructor(editor, opts) { + // Path to the project's tsconfig.json this.configFile = ""; this.isActive = false; this.isTSConfig = false; this.isTypescript = false; + // Callback that is going to be executed after the next didStopChanging event is processed this.stoppedChangingCallbacks = []; this.isOpen = false; this.occurrenceMarkers = []; @@ -23,6 +25,7 @@ class TypescriptEditorPane { if (this.isTypescript && this.filePath) { this.opts.statusPanel.show(); if (this.client) { + // The first activation might happen before we even have a client this.client.executeGetErr({ files: [this.filePath], delay: 100 @@ -76,6 +79,7 @@ class TypescriptEditorPane { this.filePath = event.path; this.isTSConfig = path_1.basename(this.filePath) === "tsconfig.json"; } + // Check if there isn't a onDidStopChanging event pending. If so, wait for it before updating if (this.changedAt && this.changedAt > (this.stoppedChangingAt | 0)) { yield new Promise(resolve => this.stoppedChangingCallbacks.push(resolve)); } @@ -192,6 +196,8 @@ class TypescriptEditorPane { }); } 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); } diff --git a/dist/main/utils/fsUtil.js b/dist/main/utils/fsUtil.js index 2669fcce8..e87235b39 100644 --- a/dist/main/utils/fsUtil.js +++ b/dist/main/utils/fsUtil.js @@ -1,17 +1,31 @@ +/** + * Wraps fs and path into a nice "consistentPath" API + */ "use strict"; +/** we work with "/" for all paths (so does the typescript language service) */ function consistentPath(filePath) { return filePath.split('\\').join('/'); } exports.consistentPath = consistentPath; const path = require("path"); +/** + * Resolves to to an absolute path. + * @param from,to,to,to... + */ function resolve(...args) { return consistentPath(path.resolve(...args)); } exports.resolve = resolve; +/** + * Could be called ends with :) + */ function isExt(path, ext) { return path && path.indexOf(ext, path.length - ext.length) !== -1; } exports.isExt = isExt; +/** + * 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] !== '.') { diff --git a/lib/client/client.ts b/lib/client/client.ts index 9bf13cbe7..f89fb0087 100644 --- a/lib/client/client.ts +++ b/lib/client/client.ts @@ -3,6 +3,20 @@ import {Transform, Readable} from "stream" import * as protocol from "typescript/lib/protocol" import byline = require("byline") +export const CommandWithResponse = new Set([ + "compileOnSaveAffectedFileList", + "compileOnSaveEmitFile", + "completionEntryDetails", + "completions", + "definition", + "occurrences", + "projectInfo", + "quickinfo", + "references", + "reload", + "rename", +]) + export class TypescriptServiceClient { /** Map of callbacks that are waiting for responses */ @@ -25,7 +39,7 @@ export class TypescriptServiceClient { server: ChildProcess /** Promise that resolves when the server is ready to accept requests */ - serverPromise: Promise + serverPromise?: Promise /** Path to the tsserver executable */ readonly tsServerPath: string @@ -37,20 +51,6 @@ export class TypescriptServiceClient { this.version = version } - static commandWithResponse = { - compileOnSaveAffectedFileList: true, - compileOnSaveEmitFile: true, - completionEntryDetails: true, - completions: true, - definition: true, - occurrences: true, - projectInfo: true, - quickinfo: true, - references: true, - reload: true, - rename: true, - } - executeChange(args: protocol.ChangeRequestArgs) { this.execute("change", args) } @@ -103,10 +103,9 @@ export class TypescriptServiceClient { return this.execute("saveto", args) } - execute(command: string, args): Promise { + private execute(command: string, args): Promise { return this.serverPromise.then(cp => { - const expectResponse = !!TypescriptServiceClient.commandWithResponse[command] - return this.sendRequest(cp, command, args, expectResponse) + return this.sendRequest(cp, command, args, CommandWithResponse.has(command)) }).catch(err => { console.log("command", command, "failed due to", err) throw err @@ -141,7 +140,7 @@ export class TypescriptServiceClient { } private emitPendingRequests() { - const pending = [] + const pending: string[] = [] for (const callback in this.callbacks) { pending.push(this.callbacks[callback].name) @@ -170,6 +169,9 @@ export class TypescriptServiceClient { } } + private sendRequest(cp: ChildProcess, command: string, args, expectResponse: true): Promise + private sendRequest(cp: ChildProcess, command: string, args, expectResponse: false): undefined + private sendRequest(cp: ChildProcess, command: string, args, expectResponse: boolean): Promise | undefined private sendRequest(cp: ChildProcess, command: string, args, expectResponse: boolean): Promise | undefined { const req = { @@ -221,7 +223,7 @@ export class TypescriptServiceClient { }) return this.serverPromise.catch(error => { - this.serverPromise = null + this.serverPromise = undefined throw error }) diff --git a/lib/client/clientResolver.ts b/lib/client/clientResolver.ts index 2096df685..5a6fd03b4 100644 --- a/lib/client/clientResolver.ts +++ b/lib/client/clientResolver.ts @@ -51,10 +51,7 @@ export class ClientResolver extends events.EventEmitter { return this.clients[serverPath].client } - const entry = this.clients[serverPath] = { - client: new Client(serverPath, version), - pending: [], - } + const entry = this.addClient(serverPath, new Client(serverPath, version)) entry.client.startServer() @@ -79,6 +76,15 @@ export class ClientResolver extends events.EventEmitter { return entry.client }) } + + addClient(serverPath: string, client: Client) { + this.clients[serverPath] = { + client, + pending: [], + } + + return this.clients[serverPath] + } } export function resolveServer(sourcePath: string): Promise { diff --git a/lib/main/atom/atomUtils.ts b/lib/main/atom/atomUtils.ts index 7c6793280..0deef2225 100644 --- a/lib/main/atom/atomUtils.ts +++ b/lib/main/atom/atomUtils.ts @@ -191,7 +191,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()); @@ -259,7 +259,7 @@ export function registerOpener(config: OpenerConfig) { 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); } diff --git a/lib/main/atom/commands/registry.ts b/lib/main/atom/commands/registry.ts index 1fac9a12c..36e693784 100644 --- a/lib/main/atom/commands/registry.ts +++ b/lib/main/atom/commands/registry.ts @@ -11,7 +11,7 @@ export interface Dependencies { } export interface CommandConstructor { - (deps: Dependencies): (e) => any + (deps: Dependencies): (e: AtomCore.CommandEvent) => any } // To allow using dependency injection, but avoid having to type a lot of boilerplate, we have the 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/tsconfig.json b/lib/tsconfig.json index b6cad2614..78e5cb36a 100644 --- a/lib/tsconfig.json +++ b/lib/tsconfig.json @@ -1,23 +1,21 @@ { - "compilerOptions": { - "target": "es6", - "module": "commonjs", - "declaration": false, - "lib": ["es6", "dom"], - "noImplicitAny": false, - "importHelpers": true, - "removeComments": true, - "noLib": false, - "noUnusedLocals": true, - "preserveConstEnums": true, - "outDir": "../dist", - "sourceMap": false, - "jsx": "react", - "types": [], - "reactNamespace": "dom" - }, - "atom": { - "formatOnSave": false - }, - "compileOnSave": true + "compilerOptions": { + "importHelpers": true, + "jsx": "react", + "lib": ["es6", "dom"], + "module": "commonjs", + "forceConsistentCasingInFileNames": true, + "noLib": false, + "noUnusedLocals": true, + "outDir": "../dist", + "preserveConstEnums": true, + "reactNamespace": "dom", + "sourceMap": false, + "strictNullChecks": false, + "target": "es6" + }, + "atom": { + "formatOnSave": false + }, + "compileOnSave": true } diff --git a/lib/typings/atom_core.d.ts b/lib/typings/atom_core.d.ts index c0d49fcb2..3498e4061 100644 --- a/lib/typings/atom_core.d.ts +++ b/lib/typings/atom_core.d.ts @@ -2,6 +2,10 @@ declare namespace AtomCore { interface IEditor { onDidChangeGrammar(callback: (grammar: IGrammar) => any): Disposable } + + interface CommandEvent extends Event { + abortKeyBinding(): any + } } declare namespace TextBuffer { From f42ee9870c78552f34525d1eb24a08538033562d Mon Sep 17 00:00:00 2001 From: Guntars Asmanis-Graham Date: Wed, 28 Dec 2016 19:09:06 -0500 Subject: [PATCH 46/70] Turn on strictNullChecks --- dist/client/client.js | 20 +- dist/main/atom/commands/build.js | 4 +- dist/main/atom/commands/checkAllFiles.js | 2 +- dist/main/atom/commands/findReferences.js | 2 +- dist/main/atom/commands/goToDeclaration.js | 2 +- dist/main/atom/commands/renameRefactor.js | 3 +- dist/main/atom/components/statusPanel.js | 8 +- dist/main/atom/tooltipManager.js | 71 ++-- dist/main/atom/views/renameView.js | 6 +- dist/main/atom/views/simpleSelectionView.js | 5 +- dist/main/atomts.js | 7 +- dist/main/lang/utils.js | 184 --------- dist/main/typescriptEditorPane.js | 4 +- dist/main/utils/fsUtil.js | 7 - lib/client/client.ts | 25 +- lib/client/findServer.ts | 2 +- lib/main/atom/autoCompleteProvider.ts | 8 +- lib/main/atom/commands/build.ts | 6 +- lib/main/atom/commands/checkAllFiles.ts | 4 +- lib/main/atom/commands/findReferences.ts | 6 +- lib/main/atom/commands/goToDeclaration.ts | 10 +- lib/main/atom/commands/renameRefactor.ts | 3 +- lib/main/atom/components/statusPanel.tsx | 16 +- lib/main/atom/tooltipManager.ts | 41 +- lib/main/atom/views/fileSymbolsView.ts | 62 --- lib/main/atom/views/mainPanelView.ts | 420 -------------------- lib/main/atom/views/projectSymbolsView.ts | 69 ---- lib/main/atom/views/renameView.ts | 4 +- lib/main/atom/views/simpleSelectionView.ts | 10 +- lib/main/atom/views/tooltipView.ts | 2 +- lib/main/atomts.ts | 10 +- lib/main/lang/utils.ts | 195 +-------- lib/main/typescriptEditorPane.ts | 8 +- lib/main/utils/fsUtil.ts | 8 - lib/tsconfig.json | 2 +- 35 files changed, 155 insertions(+), 1081 deletions(-) delete mode 100644 lib/main/atom/views/fileSymbolsView.ts delete mode 100644 lib/main/atom/views/mainPanelView.ts delete mode 100644 lib/main/atom/views/projectSymbolsView.ts diff --git a/dist/client/client.js b/dist/client/client.js index f7cc09e35..1695dd640 100644 --- a/dist/client/client.js +++ b/dist/client/client.js @@ -1,4 +1,5 @@ "use strict"; +const tslib_1 = require("tslib"); const child_process_1 = require("child_process"); const stream_1 = require("stream"); const byline = require("byline"); @@ -97,11 +98,11 @@ class TypescriptServiceClient { return this.execute("saveto", args); } execute(command, args) { - return this.serverPromise.then(cp => { - return this.sendRequest(cp, command, args, exports.CommandWithResponse.has(command)); - }).catch(err => { - console.log("command", command, "failed due to", err); - throw err; + 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) { @@ -136,15 +137,16 @@ class TypescriptServiceClient { arguments: args }; console.log("sending request", command, "with args", args); - let resultPromise = undefined; + setImmediate(() => { + cp.stdin.write(JSON.stringify(req) + "\n"); + }); if (expectResponse) { - resultPromise = new Promise((resolve, reject) => { + const resultPromise = new Promise((resolve, reject) => { this.callbacks[req.seq] = { name: command, resolve, reject, started: Date.now() }; }); this.emitPendingRequests(); + return resultPromise; } - cp.stdin.write(JSON.stringify(req) + "\n"); - return resultPromise; } startServer() { if (!this.serverPromise) { diff --git a/dist/main/atom/commands/build.js b/dist/main/atom/commands/build.js index b7fab132a..0e554d834 100644 --- a/dist/main/atom/commands/build.js +++ b/dist/main/atom/commands/build.js @@ -27,11 +27,11 @@ registry_1.commands.set("typescript:build", deps => { }).catch(() => { deps.statusPanel.setBuildStatus({ success: false }); }); - deps.statusPanel.setBuildStatus(null); + deps.statusPanel.setBuildStatus(undefined); deps.statusPanel.setProgress({ max, value: 0 }); function updateStatus() { if (files.size === 0) { - deps.statusPanel.setProgress(null); + deps.statusPanel.setProgress(undefined); } else { deps.statusPanel.setProgress({ max, value: max - files.size }); diff --git a/dist/main/atom/commands/checkAllFiles.js b/dist/main/atom/commands/checkAllFiles.js index dcf5f2420..5f40dfc76 100644 --- a/dist/main/atom/commands/checkAllFiles.js +++ b/dist/main/atom/commands/checkAllFiles.js @@ -35,7 +35,7 @@ registry_1.commands.set("typescript:check-all-files", deps => { function updateStatus() { if (files.size === 0) { unregister(); - deps.statusPanel.setProgress(null); + deps.statusPanel.setProgress(undefined); } else { deps.statusPanel.setProgress({ max, value: max - files.size }); diff --git a/dist/main/atom/commands/findReferences.js b/dist/main/atom/commands/findReferences.js index d2010cfde..0a9bf04a8 100644 --- a/dist/main/atom/commands/findReferences.js +++ b/dist/main/atom/commands/findReferences.js @@ -22,7 +22,7 @@ registry_1.commands.set("typescript:find-references", deps => {
    `; }, filterKey: 'filePath', - confirmed: open + confirmed: item => open(item) }); function open(item) { atom.workspace.open(item.file, { diff --git a/dist/main/atom/commands/goToDeclaration.js b/dist/main/atom/commands/goToDeclaration.js index e37b607a1..44bff02da 100644 --- a/dist/main/atom/commands/goToDeclaration.js +++ b/dist/main/atom/commands/goToDeclaration.js @@ -21,7 +21,7 @@ registry_1.commands.set("typescript:go-to-declaration", deps => { `; }, filterKey: 'filePath', - confirmed: open + confirmed: item => open(item) }); } else { diff --git a/dist/main/atom/commands/renameRefactor.js b/dist/main/atom/commands/renameRefactor.js index 9507ab6a3..e742c59ef 100644 --- a/dist/main/atom/commands/renameRefactor.js +++ b/dist/main/atom/commands/renameRefactor.js @@ -10,7 +10,8 @@ registry_1.commands.set("typescript:rename-refactor", deps => { } const location = atomUtils_1.getFilePathPosition(); const client = yield deps.getClient(location.file); - const { body: { info, locs } } = yield client.executeRename(location); + 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"); } diff --git a/dist/main/atom/components/statusPanel.js b/dist/main/atom/components/statusPanel.js index 655bcbd08..d4ec53dbb 100644 --- a/dist/main/atom/components/statusPanel.js +++ b/dist/main/atom/components/statusPanel.js @@ -23,11 +23,11 @@ class StatusPanel extends HTMLElement { for (const node of nodes) { this.appendChild(node); } - this.setVersion(null); + this.setVersion(undefined); this.setPending([], true); - this.setTsConfigPath(null); - this.setBuildStatus(null); - this.setProgress(null); + this.setTsConfigPath(undefined); + this.setBuildStatus(undefined); + this.setProgress(undefined); } dispose() { this.remove(); diff --git a/dist/main/atom/tooltipManager.js b/dist/main/atom/tooltipManager.js index 79b6dc0a6..cf9554af8 100644 --- a/dist/main/atom/tooltipManager.js +++ b/dist/main/atom/tooltipManager.js @@ -1,6 +1,7 @@ // Inspiration : https://atom.io/packages/ide-haskell // and https://atom.io/packages/ide-flow "use strict"; +const tslib_1 = require("tslib"); const atomUtils = require("./atomUtils"); ///ts:import:generated const atomts_1 = require("../atomts"); const path = require("path"); @@ -32,8 +33,8 @@ function attach(editorView, editor) { 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', (e) => { @@ -51,39 +52,45 @@ function attach(editorView, editor) { // Setup for clearing editor.onDidDestroy(() => deactivate()); function showExpressionType(e) { - // 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); - 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); - clientPromise.then(client => { - client.executeQuickInfo({ + 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.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; + // 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 - }).then(({ body: { displayString, documentation } }) => { - var message = `${escape(displayString)}`; - if (documentation) { - message = message + `
    ${escape(documentation).replace(/(?:\r\n|\r|\n)/g, '
    ')}
    `; - } + }).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() { @@ -102,7 +109,7 @@ function attach(editorView, editor) { if (!exprTypeTooltip) return; exprTypeTooltip.$.remove(); - exprTypeTooltip = null; + exprTypeTooltip = undefined; } } exports.attach = attach; diff --git a/dist/main/atom/views/renameView.js b/dist/main/atom/views/renameView.js index dc69f5550..7eca7752c 100644 --- a/dist/main/atom/views/renameView.js +++ b/dist/main/atom/views/renameView.js @@ -4,10 +4,6 @@ const view = require("./view"); var $ = view.$; var html = require('../../../../views/renameView.html'); class RenameView extends view.View { - constructor() { - super(...arguments); - this.editorAtRenameStart = null; - } init() { $(atom.views.getView(atom.workspace)).on('keydown', (e) => { if (e.keyCode == 27) { @@ -50,7 +46,7 @@ class RenameView extends view.View { } this.panel.hide(); this.options = {}; - this.editorAtRenameStart = null; + this.editorAtRenameStart = undefined; } renameThis(options) { this.options = options; diff --git a/dist/main/atom/views/simpleSelectionView.js b/dist/main/atom/views/simpleSelectionView.js index 906da8c61..8744865b9 100644 --- a/dist/main/atom/views/simpleSelectionView.js +++ b/dist/main/atom/views/simpleSelectionView.js @@ -24,7 +24,6 @@ class SimpleSelectListView extends sp.SelectListView { constructor(options) { super(); this.options = options; - this.panel = null; } get $() { return this; @@ -63,7 +62,9 @@ class SimpleSelectListView extends sp.SelectListView { // debugger; // DEBUG: the UI in the inspector so that it doesn't change on you } hide() { - this.panel.hide(); + if (this.panel) { + this.panel.hide(); + } this.restoreFocus(); } cancelled() { diff --git a/dist/main/atomts.js b/dist/main/atomts.js index 3d1f9fa15..a8414dde4 100644 --- a/dist/main/atomts.js +++ b/dist/main/atomts.js @@ -96,6 +96,7 @@ function activate(state) { renameView, statusPanel, }); + let activePane; const panes = []; const onSave = lodash_1.debounce((pane) => { console.log("checking errors for all panes for", pane.filePath); @@ -109,7 +110,7 @@ function activate(state) { panes.push(new typescriptEditorPane_1.TypescriptEditorPane(editor, { onDispose(pane) { if (activePane === pane) { - activePane = null; + activePane = undefined; } panes.splice(panes.indexOf(pane), 1); // Clear errors if any from this pane @@ -120,14 +121,14 @@ function activate(state) { statusPanel, })); })); - let activePane = panes.find(pane => pane.editor === atom.workspace.getActiveTextEditor()); + panes.find(pane => pane.editor === atom.workspace.getActiveTextEditor()); if (activePane) { activePane.onActivated(); } subscriptions.add(atom.workspace.onDidChangeActivePaneItem((editor) => { if (activePane) { activePane.onDeactivated(); - activePane = null; + activePane = undefined; } if (atom.workspace.isTextEditor(editor)) { const pane = panes.find(pane => pane.editor === editor); diff --git a/dist/main/lang/utils.js b/dist/main/lang/utils.js index a3b3d9d09..83e66e6d4 100644 --- a/dist/main/lang/utils.js +++ b/dist/main/lang/utils.js @@ -61,190 +61,6 @@ function pathResolve(from, to) { return result.slice(index); } exports.pathResolve = pathResolve; -class Signal { - constructor() { - /** - * list of listeners that have been suscribed to this signal - */ - this.listeners = []; - /** - * Priorities corresponding to the listeners - */ - this.priorities = []; - } - /** - * 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, 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); - } - /** - * unsubscribe a listener for the signal - * - * @params listener the previously subscribed listener - */ - remove(listener) { - 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) { - var hasBeenCanceled = this.listeners.every((listener) => { - var result = listener(parameter); - return result !== false; - }); - return hasBeenCanceled; - } - /** - * Remove all listener from the signal - */ - clear() { - this.listeners = []; - this.priorities = []; - } - /** - * @return true if the listener has been subsribed to this signal - */ - hasListeners() { - return this.listeners.length > 0; - } -} -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; -// Not optimized -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; -// Not particularly awesome e.g. '/..foo' will pass -function pathIsRelative(str) { - if (!str.length) - return false; - return str[0] == '.' || str.substring(0, 2) == "./" || str.substring(0, 3) == "../"; -} -exports.pathIsRelative = pathIsRelative; -/** Key is string. Note: this data structure might have been a bad idea. Sorry. */ -class Dict { - constructor() { - this.table = Object.create(null); - } - setValue(key, item) { - this.table[key] = item; - } - getValue(key) { return this.table[key]; } - clearValue(key) { - delete this.table[key]; - } - clearAll() { this.table = Object.create(null); } - keys() { return Object.keys(this.table); } - values() { - var array = []; - for (var key in this.table) { - array.push(this.table[key]); - } - return array; - } -} -exports.Dict = Dict; -/** for testing ui lags only */ -function delay(seconds = 2) { - delayMilliseconds(seconds * 1000); -} -exports.delay = delay; -; -function delayMilliseconds(milliseconds = 100) { - // Delay the thread - var d1 = new Date(); - var d2 = new Date(); - while (d2.valueOf() < d1.valueOf() + milliseconds) { - d2 = new Date(); - } -} -exports.delayMilliseconds = delayMilliseconds; -; -var now = () => new Date().getTime(); -function debounce(func, milliseconds, 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 = (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 */ function getName(nameLambda) { diff --git a/dist/main/typescriptEditorPane.js b/dist/main/typescriptEditorPane.js index 397b70692..27c7520c1 100644 --- a/dist/main/typescriptEditorPane.js +++ b/dist/main/typescriptEditorPane.js @@ -93,7 +93,7 @@ class TypescriptEditorPane { if (this.isTypescript && this.filePath) { if (this.isOpen) { if (changes.length !== 0) { - this.opts.statusPanel.setBuildStatus(null); + this.opts.statusPanel.setBuildStatus(undefined); } for (const change of changes) { const { start, oldExtent, newText } = change; @@ -172,7 +172,7 @@ class TypescriptEditorPane { const result = yield this.client.executeCompileOnSaveAffectedFileList({ file: this.filePath }); - this.opts.statusPanel.setBuildStatus(null); + this.opts.statusPanel.setBuildStatus(undefined); const fileNames = lodash_1.flatten(result.body.map(project => project.fileNames)); if (fileNames.length === 0) { return; diff --git a/dist/main/utils/fsUtil.js b/dist/main/utils/fsUtil.js index e87235b39..f691f5e28 100644 --- a/dist/main/utils/fsUtil.js +++ b/dist/main/utils/fsUtil.js @@ -16,13 +16,6 @@ function resolve(...args) { return consistentPath(path.resolve(...args)); } exports.resolve = resolve; -/** - * Could be called ends with :) - */ -function isExt(path, ext) { - return path && path.indexOf(ext, path.length - ext.length) !== -1; -} -exports.isExt = isExt; /** * Converts "C:\boo" , "C:\boo\foo.ts" => "./foo.ts"; Works on unix as well. */ diff --git a/lib/client/client.ts b/lib/client/client.ts index f89fb0087..d05946627 100644 --- a/lib/client/client.ts +++ b/lib/client/client.ts @@ -103,13 +103,12 @@ export class TypescriptServiceClient { return this.execute("saveto", args) } - private execute(command: string, args): Promise { - return this.serverPromise.then(cp => { - return this.sendRequest(cp, command, args, CommandWithResponse.has(command)) - }).catch(err => { - console.log("command", command, "failed due to", err) - throw err - }) + private async execute(command: string, args) { + 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 */ @@ -182,19 +181,19 @@ export class TypescriptServiceClient { console.log("sending request", command, "with args", args) - let resultPromise: Promise | undefined = undefined + setImmediate(() => { + cp.stdin.write(JSON.stringify(req) + "\n") + }) if (expectResponse) { - resultPromise = new Promise((resolve, reject) => { + const resultPromise = new Promise((resolve, reject) => { this.callbacks[req.seq] = {name: command, resolve, reject, started: Date.now()} }) this.emitPendingRequests() - } - cp.stdin.write(JSON.stringify(req) + "\n") - - return resultPromise + return resultPromise + } } startServer() { diff --git a/lib/client/findServer.ts b/lib/client/findServer.ts index a56a074f6..d43e098ca 100644 --- a/lib/client/findServer.ts +++ b/lib/client/findServer.ts @@ -57,7 +57,7 @@ export function findTypescriptServers(root: string): Promise { } /** Get info about the tsserver at the prefix */ -function getServerInfo(prefix: string, callback: (err: Error, info: Server) => any) { +function getServerInfo(prefix: string, callback: (err: Error | null, info: Server | null) => any) { const tsDir = path.join(prefix, "node_modules", "typescript") fs.readFile(path.join(tsDir, "package.json"), "utf8", (err, pkg) => { diff --git a/lib/main/atom/autoCompleteProvider.ts b/lib/main/atom/autoCompleteProvider.ts index b2b31089b..a15ab5eff 100644 --- a/lib/main/atom/autoCompleteProvider.ts +++ b/lib/main/atom/autoCompleteProvider.ts @@ -56,7 +56,7 @@ export class AutocompleteProvider implements Provider { const client = await this.clientResolver.get(location.file) const completions = await client.executeCompletions({prefix, ...location}) - const suggestions = completions.body.map(entry => ({ + const suggestions = completions.body!.map(entry => ({ text: entry.name, leftLabel: entry.kind, type: kindToType(entry.kind), @@ -99,7 +99,7 @@ export class AutocompleteProvider implements Provider { const trimmed = prefix.trim() return suggestions.map(suggestion => ({ - replacementPrefix: getReplacementPrefix(prefix, trimmed, suggestion.text), + replacementPrefix: getReplacementPrefix(prefix, trimmed, suggestion.text!), ...suggestion })) } @@ -107,11 +107,11 @@ export class AutocompleteProvider implements Provider { 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), + entryNames: suggestions.map(s => s.text!), ...location }) - details.body.forEach((detail, i) => { + details.body!.forEach((detail, i) => { const suggestion = suggestions[i] suggestion.details = detail diff --git a/lib/main/atom/commands/build.ts b/lib/main/atom/commands/build.ts index 65a602467..b15f51e01 100644 --- a/lib/main/atom/commands/build.ts +++ b/lib/main/atom/commands/build.ts @@ -15,7 +15,7 @@ commands.set("typescript:build", deps => { needFileNameList: true }) - const files = new Set(projectInfo.body.fileNames) + const files = new Set(projectInfo.body!.fileNames) const max = files.size const promises = [...files.values()].map(file => _finally(client.executeCompileOnSaveEmitFile({file, forced: true}), () => { @@ -34,12 +34,12 @@ commands.set("typescript:build", deps => { deps.statusPanel.setBuildStatus({success: false}) }) - deps.statusPanel.setBuildStatus(null) + deps.statusPanel.setBuildStatus(undefined) deps.statusPanel.setProgress({max, value: 0}) function updateStatus() { if (files.size === 0) { - deps.statusPanel.setProgress(null) + deps.statusPanel.setProgress(undefined) } else { deps.statusPanel.setProgress({max, value: max - files.size}) } diff --git a/lib/main/atom/commands/checkAllFiles.ts b/lib/main/atom/commands/checkAllFiles.ts index 884a2a2f1..7e884e2bc 100644 --- a/lib/main/atom/commands/checkAllFiles.ts +++ b/lib/main/atom/commands/checkAllFiles.ts @@ -15,7 +15,7 @@ commands.set("typescript:check-all-files", deps => { needFileNameList: true }) - const files = new Set(projectInfo.body.fileNames) + 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 @@ -43,7 +43,7 @@ commands.set("typescript:check-all-files", deps => { function updateStatus() { if (files.size === 0) { unregister() - deps.statusPanel.setProgress(null) + deps.statusPanel.setProgress(undefined) } else { deps.statusPanel.setProgress({max, value: max - files.size}) } diff --git a/lib/main/atom/commands/findReferences.ts b/lib/main/atom/commands/findReferences.ts index 905752dd9..036ad6c35 100644 --- a/lib/main/atom/commands/findReferences.ts +++ b/lib/main/atom/commands/findReferences.ts @@ -14,7 +14,7 @@ commands.set("typescript:find-references", deps => { const result = await client.executeReferences(location) simpleSelectionView({ - items: result.body.refs, + items: result.body!.refs, viewForItem: item => { return `
    ${atom.project.relativize(item.file)} @@ -23,10 +23,10 @@ commands.set("typescript:find-references", deps => {
    ` }, filterKey: 'filePath', - confirmed: open + confirmed: item => open(item) }) - function open(item: typeof result.body.refs[0]) { + 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/goToDeclaration.ts b/lib/main/atom/commands/goToDeclaration.ts index 53a751c51..909e66553 100644 --- a/lib/main/atom/commands/goToDeclaration.ts +++ b/lib/main/atom/commands/goToDeclaration.ts @@ -12,9 +12,9 @@ commands.set("typescript:go-to-declaration", deps => { const client = await deps.getClient(location.file) const result = await client.executeDefinition(location) - if (result.body.length > 1) { + if (result.body!.length > 1) { simpleSelectionView({ - items: result.body, + items: result.body!, viewForItem: item => { return ` ${item.file} @@ -22,13 +22,13 @@ commands.set("typescript:go-to-declaration", deps => { ` }, filterKey: 'filePath', - confirmed: open + confirmed: item => open(item) }) } else { - open(result.body[0]) + open(result.body![0]) } - function open(item: typeof result.body[0]) { + 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/renameRefactor.ts b/lib/main/atom/commands/renameRefactor.ts index 37fd05c6c..5c8458494 100644 --- a/lib/main/atom/commands/renameRefactor.ts +++ b/lib/main/atom/commands/renameRefactor.ts @@ -10,7 +10,8 @@ commands.set("typescript:rename-refactor", deps => { const location = getFilePathPosition() const client = await deps.getClient(location.file) - const {body: {info, locs}} = await client.executeRename(location) + 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") diff --git a/lib/main/atom/components/statusPanel.tsx b/lib/main/atom/components/statusPanel.tsx index 6f431d874..88037f5f0 100644 --- a/lib/main/atom/components/statusPanel.tsx +++ b/lib/main/atom/components/statusPanel.tsx @@ -16,7 +16,7 @@ export class StatusPanel extends HTMLElement { private statusText: HTMLElement private version: HTMLElement - private configPath: string + private configPath?: string private pendingRequests: string[] private pendingTimeout: any @@ -56,11 +56,11 @@ export class StatusPanel extends HTMLElement { this.appendChild(node) } - this.setVersion(null) + this.setVersion(undefined) this.setPending([], true) - this.setTsConfigPath(null) - this.setBuildStatus(null) - this.setProgress(null) + this.setTsConfigPath(undefined) + this.setBuildStatus(undefined) + this.setProgress(undefined) } dispose() { @@ -75,7 +75,7 @@ export class StatusPanel extends HTMLElement { } } - setBuildStatus(status: {success: boolean}) { + setBuildStatus(status?: {success: boolean}) { const container = this.statusText if (status) { if (status.success) { @@ -103,7 +103,7 @@ export class StatusPanel extends HTMLElement { } } - setTsConfigPath(configPath: string) { + setTsConfigPath(configPath?: string) { this.configPath = configPath if (configPath) { @@ -116,7 +116,7 @@ export class StatusPanel extends HTMLElement { } } - setVersion(version: string) { + setVersion(version?: string) { if (version) { this.version.textContent = version this.version.classList.remove("hide") diff --git a/lib/main/atom/tooltipManager.ts b/lib/main/atom/tooltipManager.ts index 2ae65d268..1f92ac798 100644 --- a/lib/main/atom/tooltipManager.ts +++ b/lib/main/atom/tooltipManager.ts @@ -36,8 +36,8 @@ export function attach(editorView: JQuery, editor: AtomCore.IEditor) { 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; @@ -60,7 +60,7 @@ export function attach(editorView: JQuery, editor: AtomCore.IEditor) { // 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; @@ -85,19 +85,26 @@ export function attach(editorView: JQuery, editor: AtomCore.IEditor) { }; exprTypeTooltip = new TooltipView(tooltipRect); - clientPromise.then(client => { - client.executeQuickInfo({ - file: filePath, - line: bufferPt.row+1, - offset: bufferPt.column+1 - }).then(({body: {displayString, documentation}}) => { - var message = `${escape(displayString) }`; - if (documentation) { - message = message + `
    ${escape(documentation).replace(/(?:\r\n|\r|\n)/g, '
    ') }
    `; - } - exprTypeTooltip.updateText(message); - }, () => { /* ignore the errors */ }) - }) + 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() { @@ -115,7 +122,7 @@ export function attach(editorView: JQuery, editor: AtomCore.IEditor) { function hideExpressionType() { if (!exprTypeTooltip) return; exprTypeTooltip.$.remove(); - exprTypeTooltip = null; + exprTypeTooltip = undefined; } } diff --git a/lib/main/atom/views/fileSymbolsView.ts b/lib/main/atom/views/fileSymbolsView.ts deleted file mode 100644 index 585fe292f..000000000 --- a/lib/main/atom/views/fileSymbolsView.ts +++ /dev/null @@ -1,62 +0,0 @@ -import sp = require('atom-space-pen-views'); -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/mainPanelView.ts b/lib/main/atom/views/mainPanelView.ts deleted file mode 100644 index dc7ec0620..000000000 --- a/lib/main/atom/views/mainPanelView.ts +++ /dev/null @@ -1,420 +0,0 @@ -import view = require('./view'); - -import lineMessageView = require('./lineMessageView'); -import atomUtils = require("../atomUtils"); - -const panelHeaders = { - build: 'Last Build Output', - references: 'References' -} - -import gotoHistory = require('../gotoHistory'); - -export class MainPanelView extends view.View { - - private tsconfigInUse: JQuery; - - private buildPanelBtn: JQuery; - private referencesPanelBtn: 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('build', panelHeaders.build, 'selected') - 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: '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() { - console.log("soft reset") - // 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); - } - } - - 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.buildPanelBtn, this.referencesPanelBtn]; - var bodies = [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.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 }); - } - } - - ///////////////////// 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 interface MainPanel { - show() - hide() - view: MainPanelView -} - -export function attach(): MainPanel { - const view = new MainPanelView({}) - - atom.workspace.addBottomPanel({ item: view, priority: 1000, visible: true }) - - return { - show() { view.$.show() }, - hide() { view.$.hide() }, - view - } -} diff --git a/lib/main/atom/views/projectSymbolsView.ts b/lib/main/atom/views/projectSymbolsView.ts deleted file mode 100644 index 6b78c4f5e..000000000 --- a/lib/main/atom/views/projectSymbolsView.ts +++ /dev/null @@ -1,69 +0,0 @@ -import sp = require('atom-space-pen-views'); -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/renameView.ts b/lib/main/atom/views/renameView.ts index 1517c8c0a..845eeadff 100644 --- a/lib/main/atom/views/renameView.ts +++ b/lib/main/atom/views/renameView.ts @@ -64,7 +64,7 @@ export class RenameView this.panel = panel } - public editorAtRenameStart: AtomCore.IEditor = null; + public editorAtRenameStart?: AtomCore.IEditor; public clearView() { if (this.editorAtRenameStart && !this.editorAtRenameStart.isDestroyed()) { var view = atom.views.getView(this.editorAtRenameStart); @@ -72,7 +72,7 @@ export class RenameView } this.panel.hide(); this.options = {}; - this.editorAtRenameStart = null; + this.editorAtRenameStart = undefined; } private renameThis(options: RenameViewOptions) { diff --git a/lib/main/atom/views/simpleSelectionView.ts b/lib/main/atom/views/simpleSelectionView.ts index 765ea2ab6..27f32e2c4 100644 --- a/lib/main/atom/views/simpleSelectionView.ts +++ b/lib/main/atom/views/simpleSelectionView.ts @@ -69,7 +69,7 @@ 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 }); @@ -79,12 +79,14 @@ export class SimpleSelectListView extends sp.SelectListView { // 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/atomts.ts b/lib/main/atomts.ts index 3cce6dcd9..6999848fe 100644 --- a/lib/main/atomts.ts +++ b/lib/main/atomts.ts @@ -112,6 +112,7 @@ export function activate(state: PackageState) { statusPanel, }) + let activePane: TypescriptEditorPane | undefined const panes: TypescriptEditorPane[] = [] const onSave = debounce((pane: TypescriptEditorPane) => { @@ -130,7 +131,7 @@ export function activate(state: PackageState) { panes.push(new TypescriptEditorPane(editor, { onDispose(pane) { if (activePane === pane) { - activePane = null + activePane = undefined } panes.splice(panes.indexOf(pane), 1) @@ -144,8 +145,7 @@ export function activate(state: PackageState) { })) })) - let activePane: TypescriptEditorPane = panes.find(pane => - pane.editor === atom.workspace.getActiveTextEditor()) + panes.find(pane => pane.editor === atom.workspace.getActiveTextEditor()) if (activePane) { activePane.onActivated() @@ -154,7 +154,7 @@ export function activate(state: PackageState) { subscriptions.add(atom.workspace.onDidChangeActivePaneItem((editor: AtomCore.IEditor) => { if (activePane) { activePane.onDeactivated() - activePane = null + activePane = undefined } if (atom.workspace.isTextEditor(editor)) { @@ -204,7 +204,7 @@ export function getHyperclickProvider() { 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) + return tsconfig.load(result.body!.configFileName) }) }) } 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/typescriptEditorPane.ts b/lib/main/typescriptEditorPane.ts index cd44e3727..2f702a65b 100644 --- a/lib/main/typescriptEditorPane.ts +++ b/lib/main/typescriptEditorPane.ts @@ -96,7 +96,7 @@ export class TypescriptEditorPane implements AtomCore.Disposable { needFileNameList: false, file: this.filePath }).then(result => { - this.configFile = result.body.configFileName + this.configFile = result.body!.configFileName if (this.isActive) { this.opts.statusPanel.setTsConfigPath(this.configFile) @@ -164,7 +164,7 @@ export class TypescriptEditorPane implements AtomCore.Disposable { }).then(result => { this.clearOccurrenceMarkers() - for (const ref of result.body) { + for (const ref of result.body!) { const marker = this.editor.markBufferRange(spanToRange(ref)) this.editor.decorateMarker(marker as any, { type: "highlight", @@ -216,7 +216,7 @@ export class TypescriptEditorPane implements AtomCore.Disposable { file: this.filePath }) - this.opts.statusPanel.setBuildStatus(null) + this.opts.statusPanel.setBuildStatus(undefined) const fileNames = flatten(result.body.map(project => project.fileNames)) @@ -251,7 +251,7 @@ export class TypescriptEditorPane implements AtomCore.Disposable { if (this.isOpen) { if (changes.length !== 0) { - this.opts.statusPanel.setBuildStatus(null) + this.opts.statusPanel.setBuildStatus(undefined) } for (const change of changes) { diff --git a/lib/main/utils/fsUtil.ts b/lib/main/utils/fsUtil.ts index f5d1af65f..b164ff4b2 100644 --- a/lib/main/utils/fsUtil.ts +++ b/lib/main/utils/fsUtil.ts @@ -17,14 +17,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. */ diff --git a/lib/tsconfig.json b/lib/tsconfig.json index 78e5cb36a..a48b50232 100644 --- a/lib/tsconfig.json +++ b/lib/tsconfig.json @@ -11,7 +11,7 @@ "preserveConstEnums": true, "reactNamespace": "dom", "sourceMap": false, - "strictNullChecks": false, + "strictNullChecks": true, "target": "es6" }, "atom": { From 8e7d942ad56e37e85263386d072993b7b160f28a Mon Sep 17 00:00:00 2001 From: Guntars Asmanis-Graham Date: Fri, 30 Dec 2016 20:39:20 -0500 Subject: [PATCH 47/70] Use EventEmitter instead of custom code in Client --- lib/client/client.ts | 48 +++++++++++++++----------------------------- 1 file changed, 16 insertions(+), 32 deletions(-) diff --git a/lib/client/client.ts b/lib/client/client.ts index d05946627..85b45ed94 100644 --- a/lib/client/client.ts +++ b/lib/client/client.ts @@ -1,4 +1,5 @@ import {ChildProcess, spawn} from "child_process" +import {EventEmitter} from "events" import {Transform, Readable} from "stream" import * as protocol from "typescript/lib/protocol" import byline = require("byline") @@ -29,10 +30,7 @@ export class TypescriptServiceClient { } } = {} - private listeners: { - [event: string]: ((event: any) => any)[] - } = {} - + private events = new EventEmitter() private seq = 0 /** The tsserver child process */ @@ -51,11 +49,11 @@ export class TypescriptServiceClient { this.version = version } - executeChange(args: protocol.ChangeRequestArgs) { - this.execute("change", args) + executeChange(args: protocol.ChangeRequestArgs): Promise { + return this.execute("change", args) } - executeClose(args: protocol.FileRequestArgs) { - this.execute("close", args) + executeClose(args: protocol.FileRequestArgs): Promise { + return this.execute("close", args) } executeCompileOnSaveAffectedFileList(args: protocol.FileRequestArgs): Promise { return this.execute("compileOnSaveAffectedFileList", args) @@ -72,17 +70,17 @@ export class TypescriptServiceClient { executeDefinition(args: protocol.FileLocationRequestArgs): Promise { return this.execute("definition", args) } - executeGetErr(args: protocol.GeterrRequestArgs) { - this.execute("geterr", args) + executeGetErr(args: protocol.GeterrRequestArgs): Promise { + return this.execute("geterr", args) } - executeGetErrForProject(args: protocol.GeterrForProjectRequestArgs) { - this.execute("geterrForProject", 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) { - this.execute("open", args) + executeOpen(args: protocol.OpenRequestArgs): Promise { + return this.execute("open", args) } executeProjectInfo(args: protocol.ProjectInfoRequestArgs): Promise { return this.execute("projectInfo", args) @@ -117,24 +115,10 @@ export class TypescriptServiceClient { 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 { - if (this.listeners[name] === undefined) { - this.listeners[name] = [] - } - - this.listeners[name].push(listener) + this.events.on(name, listener) return () => { - const idx = this.listeners[name].indexOf(listener) - this.listeners[name].splice(idx, 1) - } - } - - private emit(name: string, data: any) { - const listeners = this.listeners[name] - if (listeners) { - for (const listener of listeners) { - listener(data) - } + this.events.removeListener(name, listener) } } @@ -145,7 +129,7 @@ export class TypescriptServiceClient { pending.push(this.callbacks[callback].name) } - this.emit("pendingRequestsChange", pending) + this.events.emit("pendingRequestsChange", pending) } private onMessage = (res: protocol.Response | protocol.Event) => { @@ -164,7 +148,7 @@ export class TypescriptServiceClient { } } else if (isEvent(res)) { console.log("received event", res) - this.emit(res.event, res.body) + this.events.emit(res.event, res.body) } } From eafb1fe44644b2ccb189213ec1954eacad764308 Mon Sep 17 00:00:00 2001 From: Guntars Asmanis-Graham Date: Fri, 30 Dec 2016 20:39:53 -0500 Subject: [PATCH 48/70] Create a TypescriptBuffer class that wraps Buffer --- dist/client/client.js | 33 ++---- dist/main/atom/atomUtils.js | 13 ++- dist/main/atomts.js | 1 + dist/main/typescriptBuffer.js | 81 +++++++++++++++ dist/main/typescriptEditorPane.js | 109 +++++++------------- lib/main/atom/atomUtils.ts | 19 ++-- lib/main/atomts.ts | 1 + lib/main/typescriptBuffer.ts | 119 +++++++++++++++++++++ lib/main/typescriptEditorPane.ts | 166 ++++++++++-------------------- lib/typings/atom_core.d.ts | 16 ++- 10 files changed, 346 insertions(+), 212 deletions(-) create mode 100644 dist/main/typescriptBuffer.js create mode 100644 lib/main/typescriptBuffer.ts diff --git a/dist/client/client.js b/dist/client/client.js index 1695dd640..dc94eac81 100644 --- a/dist/client/client.js +++ b/dist/client/client.js @@ -1,6 +1,7 @@ "use strict"; const tslib_1 = require("tslib"); const child_process_1 = require("child_process"); +const events_1 = require("events"); const stream_1 = require("stream"); const byline = require("byline"); exports.CommandWithResponse = new Set([ @@ -20,7 +21,7 @@ class TypescriptServiceClient { constructor(tsServerPath, version) { /** Map of callbacks that are waiting for responses */ this.callbacks = {}; - this.listeners = {}; + this.events = new events_1.EventEmitter(); this.seq = 0; this.tsServerArgs = []; this.onMessage = (res) => { @@ -40,17 +41,17 @@ class TypescriptServiceClient { } else if (isEvent(res)) { console.log("received event", res); - this.emit(res.event, res.body); + this.events.emit(res.event, res.body); } }; this.tsServerPath = tsServerPath; this.version = version; } executeChange(args) { - this.execute("change", args); + return this.execute("change", args); } executeClose(args) { - this.execute("close", args); + return this.execute("close", args); } executeCompileOnSaveAffectedFileList(args) { return this.execute("compileOnSaveAffectedFileList", args); @@ -68,16 +69,16 @@ class TypescriptServiceClient { return this.execute("definition", args); } executeGetErr(args) { - this.execute("geterr", args); + return this.execute("geterr", args); } executeGetErrForProject(args) { - this.execute("geterrForProject", args); + return this.execute("geterrForProject", args); } executeOccurances(args) { return this.execute("occurrences", args); } executeOpen(args) { - this.execute("open", args); + return this.execute("open", args); } executeProjectInfo(args) { return this.execute("projectInfo", args); @@ -106,29 +107,17 @@ class TypescriptServiceClient { }); } on(name, listener) { - if (this.listeners[name] === undefined) { - this.listeners[name] = []; - } - this.listeners[name].push(listener); + this.events.on(name, listener); return () => { - const idx = this.listeners[name].indexOf(listener); - this.listeners[name].splice(idx, 1); + this.events.removeListener(name, listener); }; } - emit(name, data) { - const listeners = this.listeners[name]; - if (listeners) { - for (const listener of listeners) { - listener(data); - } - } - } emitPendingRequests() { const pending = []; for (const callback in this.callbacks) { pending.push(this.callbacks[callback].name); } - this.emit("pendingRequestsChange", pending); + this.events.emit("pendingRequestsChange", pending); } sendRequest(cp, command, args, expectResponse) { const req = { diff --git a/dist/main/atom/atomUtils.js b/dist/main/atom/atomUtils.js index 807d713b0..b446099dc 100644 --- a/dist/main/atom/atomUtils.js +++ b/dist/main/atom/atomUtils.js @@ -1,9 +1,9 @@ "use strict"; const tslib_1 = require("tslib"); -const path = require("path"); +const Atom = require("atom"); const fs = require("fs"); const fsu = require("../utils/fsUtil"); -const _atom = require("atom"); +const path = require("path"); const url = require("url"); // Return line/offset position in the editor using 1-indexed coordinates function getEditorPosition(editor) { @@ -14,6 +14,13 @@ function getEditorPosition(editor) { }; } exports.getEditorPosition = getEditorPosition; +function isTypescriptFile(filePath) { + if (!filePath) + return false; + const ext = path.extname(filePath); + return ext === ".ts" || ext === ".tsx"; +} +exports.isTypescriptFile = isTypescriptFile; function isAllowedExtension(ext) { return (ext == '.ts' || ext == '.tst' || ext == '.tsx'); } @@ -91,7 +98,7 @@ exports.getEditorsForAllPaths = getEditorsForAllPaths; function getRangeForTextSpan(editor, ts) { 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; diff --git a/dist/main/atomts.js b/dist/main/atomts.js index a8414dde4..d2b3bd593 100644 --- a/dist/main/atomts.js +++ b/dist/main/atomts.js @@ -108,6 +108,7 @@ function activate(state) { }, 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; diff --git a/dist/main/typescriptBuffer.js b/dist/main/typescriptBuffer.js new file mode 100644 index 000000000..d3a1d22ce --- /dev/null +++ b/dist/main/typescriptBuffer.js @@ -0,0 +1,81 @@ +"use strict"; +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 atomUtils_1 = require("./atom/atomUtils"); +class TypescriptBuffer { + constructor(buffer, getClient) { + this.buffer = buffer; + this.getClient = getClient; + this.events = new events_1.EventEmitter(); + this.subscriptions = new atom_1.CompositeDisposable(); + this.dispose = () => { + console.warn("buffer disposed"); + this.subscriptions.dispose(); + if (this.isOpen) { + 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 = 0, changedAtBatch = 0 } = 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) { + return; + } + console.warn("onDidStopChanging", this, changes); + 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(tslib_1.__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.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 (atomUtils_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"); + } + else { + this.clientPromise = Promise.reject(new Error("Missing filePath or not a Typescript file")); + } + }); + } + on(name, callback) { + this.events.on(name, callback); + return this; + } +} +exports.TypescriptBuffer = TypescriptBuffer; diff --git a/dist/main/typescriptEditorPane.js b/dist/main/typescriptEditorPane.js index 27c7520c1..b722bc062 100644 --- a/dist/main/typescriptEditorPane.js +++ b/dist/main/typescriptEditorPane.js @@ -2,10 +2,10 @@ const tslib_1 = require("tslib"); const atom_space_pen_views_1 = require("atom-space-pen-views"); const path_1 = require("path"); -const atomts_1 = require("./atomts"); const atom_1 = require("atom"); const lodash_1 = require("lodash"); const tsUtil_1 = require("./utils/tsUtil"); +const typescriptBuffer_1 = require("./typescriptBuffer"); const tooltipManager = require("./atom/tooltipManager"); class TypescriptEditorPane { constructor(editor, opts) { @@ -14,8 +14,6 @@ class TypescriptEditorPane { this.isActive = false; this.isTSConfig = false; this.isTypescript = false; - // Callback that is going to be executed after the next didStopChanging event is processed - this.stoppedChangingCallbacks = []; this.isOpen = false; this.occurrenceMarkers = []; this.subscriptions = new atom_1.CompositeDisposable(); @@ -35,13 +33,18 @@ class TypescriptEditorPane { } this.opts.statusPanel.setTsConfigPath(this.configFile); }; + this.onChanged = () => { + console.warn("changed event"); + this.opts.statusPanel.setBuildStatus(undefined); + this.client.executeGetErr({ + files: [this.filePath], + delay: 100 + }); + }; this.onDeactivated = () => { this.isActive = false; this.opts.statusPanel.hide(); }; - this.onDidChange = diff => { - this.changedAt = Date.now(); - }; this.updateMarkers = lodash_1.debounce(() => { const pos = this.editor.getLastCursor().getBufferPosition(); this.client.executeOccurances({ @@ -73,70 +76,15 @@ class TypescriptEditorPane { this.onDidDestroy = () => { this.dispose(); }; - this.onDidSave = (event) => tslib_1.__awaiter(this, void 0, void 0, function* () { - if (this.filePath !== event.path) { - this.client = yield atomts_1.clientResolver.get(event.path); - this.filePath = event.path; - this.isTSConfig = path_1.basename(this.filePath) === "tsconfig.json"; - } - // Check if there isn't a onDidStopChanging event pending. If so, wait for it before updating - if (this.changedAt && this.changedAt > (this.stoppedChangingAt | 0)) { - yield new Promise(resolve => this.stoppedChangingCallbacks.push(resolve)); - } - if (this.opts.onSave) { - this.opts.onSave(this); - } - this.compileOnSave(); - }); - this.onDidStopChanging = ({ changes }) => { - this.stoppedChangingAt = Date.now(); - if (this.isTypescript && this.filePath) { - if (this.isOpen) { - if (changes.length !== 0) { - this.opts.statusPanel.setBuildStatus(undefined); - } - 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 - }; - this.client.executeChange(tslib_1.__assign({}, end, { file: this.filePath, line: start.row + 1, offset: start.column + 1, insertString: newText })); - } - } - this.client.executeGetErr({ - files: [this.filePath], - delay: 100 - }); - } - this.stoppedChangingCallbacks.forEach(fn => fn()); - this.stoppedChangingCallbacks.length = 0; - }; - this.editor = editor; - this.filePath = editor.getPath(); - this.opts = opts; - this.isTypescript = isTypescriptGrammar(editor.getGrammar()); - this.subscriptions.add(editor.onDidChangeGrammar(grammar => { - this.isTypescript = isTypescriptGrammar(grammar); - })); - if (this.filePath) { - this.isTSConfig = path_1.basename(this.filePath) === "tsconfig.json"; - } - atomts_1.clientResolver.get(this.filePath).then(client => { - this.client = client; - this.subscriptions.add(editor.buffer.onDidChange(this.onDidChange)); - this.subscriptions.add(editor.onDidChangeCursorPosition(this.onDidChangeCursorPosition)); - this.subscriptions.add(editor.onDidSave(this.onDidSave)); - this.subscriptions.add(editor.onDidStopChanging(this.onDidStopChanging)); - this.subscriptions.add(editor.onDidDestroy(this.onDidDestroy)); + this.onOpened = () => tslib_1.__awaiter(this, void 0, void 0, function* () { + console.warn("opened event"); + this.client = yield this.opts.getClient(this.filePath); + this.subscriptions.add(this.editor.onDidChangeCursorPosition(this.onDidChangeCursorPosition)); + this.subscriptions.add(this.editor.onDidDestroy(this.onDidDestroy)); if (this.isActive) { this.opts.statusPanel.setVersion(this.client.version); } if (this.isTypescript && this.filePath) { - this.client.executeOpen({ - file: this.filePath, - fileContent: this.editor.getText() - }); this.client.executeGetErr({ files: [this.filePath], delay: 100 @@ -153,13 +101,36 @@ class TypescriptEditorPane { }, error => null); } }); + this.onSaved = () => { + console.warn("saved event"); + if (this.opts.onSave) { + this.opts.onSave(this); + } + this.compileOnSave(); + // if (this.filePath !== event.path) { + // this.client = await this.opts.getClient(event.path) + // this.filePath = event.path + // this.isTSConfig = basename(this.filePath) === "tsconfig.json" + // } + }; + 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()); + this.subscriptions.add(editor.onDidChangeGrammar(grammar => { + this.isTypescript = isTypescriptGrammar(grammar); + })); + if (this.filePath) { + this.isTSConfig = path_1.basename(this.filePath) === "tsconfig.json"; + } this.setupTooltipView(); } dispose() { this.subscriptions.dispose(); - if (this.isOpen) { - this.client.executeClose({ file: this.filePath }); - } this.opts.onDispose(this); } clearOccurrenceMarkers() { diff --git a/lib/main/atom/atomUtils.ts b/lib/main/atom/atomUtils.ts index 0deef2225..9916c62de 100644 --- a/lib/main/atom/atomUtils.ts +++ b/lib/main/atom/atomUtils.ts @@ -1,8 +1,8 @@ -import path = require('path'); -import fs = require('fs'); -import * as fsu from "../utils/fsUtil"; -import _atom = require('atom'); -import url = require('url'); +import * as Atom from "atom" +import * as fs from "fs" +import * as fsu from "../utils/fsUtil" +import * as path from "path" +import * as url from "url" export interface LocationQuery { line: number @@ -22,6 +22,13 @@ export function getEditorPosition(editor: AtomCore.IEditor): LocationQuery { } } +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) { return (ext == '.ts' || ext == '.tst' || ext == '.tsx'); } @@ -106,7 +113,7 @@ export function getEditorsForAllPaths(filePaths: string[]): Promise<{ [filePath: export function getRangeForTextSpan(editor: AtomCore.IEditor, ts: { start: number; length: number }): TextBuffer.IRange { 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; } diff --git a/lib/main/atomts.ts b/lib/main/atomts.ts index 6999848fe..5eff72b89 100644 --- a/lib/main/atomts.ts +++ b/lib/main/atomts.ts @@ -129,6 +129,7 @@ export function activate(state: PackageState) { 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 diff --git a/lib/main/typescriptBuffer.ts b/lib/main/typescriptBuffer.ts new file mode 100644 index 000000000..fbcfb7900 --- /dev/null +++ b/lib/main/typescriptBuffer.ts @@ -0,0 +1,119 @@ +// 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/atomUtils" + +export class TypescriptBuffer { + // Timestamps for buffer events + changedAt: number + changedAtBatch: number + + // Promise that resolves to the correct client for this filePath + 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.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") + } else { + this.clientPromise = Promise.reject(new Error("Missing filePath or not a Typescript file")) + } + } + + dispose = () => { + console.warn("buffer disposed") + this.subscriptions.dispose() + + if (this.isOpen) { + 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 = 0, changedAtBatch = 0} = this + if (changedAt && changedAt > changedAtBatch) { + await new Promise(resolve => this.events.once("changed", resolve)) + } + + this.events.emit("saved") + } + + onDidStopChanging = async ({changes}) => { + // 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) { + return + } + + console.warn("onDidStopChanging", this, changes) + + 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 index 2f702a65b..a5b301408 100644 --- a/lib/main/typescriptEditorPane.ts +++ b/lib/main/typescriptEditorPane.ts @@ -1,33 +1,25 @@ import {$} from "atom-space-pen-views" import {basename} from "path" -import {clientResolver} from "./atomts" import {CompositeDisposable} from "atom" import {debounce, flatten} from "lodash" import {spanToRange} from "./utils/tsUtil" import {TypescriptServiceClient} from "../client/client" +import {TypescriptBuffer} from "./typescriptBuffer" import {StatusPanel} from "./atom/components/statusPanel" import * as tooltipManager from './atom/tooltipManager' -type onChangeObserver = (diff: { - oldRange: TextBuffer.IRange - newRange: TextBuffer.IRange - oldText: string - newText: string -}) => any - interface PaneOptions { + getClient: (filePath: string) => Promise onDispose: (pane: TypescriptEditorPane) => any onSave: (pane: TypescriptEditorPane) => any statusPanel: StatusPanel } export class TypescriptEditorPane implements AtomCore.Disposable { - // Timestamp for didChange event - changedAt: number - // Timestamp for activated event activeAt: number + buffer: TypescriptBuffer client: TypescriptServiceClient // Path to the project's tsconfig.json @@ -38,12 +30,6 @@ export class TypescriptEditorPane implements AtomCore.Disposable { isTSConfig = false isTypescript = false - // Timestamp for last didStopChanging event - stoppedChangingAt: number - - // Callback that is going to be executed after the next didStopChanging event is processed - stoppedChangingCallbacks: Function[] = [] - private opts: PaneOptions private isOpen = false @@ -55,6 +41,10 @@ export class TypescriptEditorPane implements AtomCore.Disposable { 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()) @@ -66,55 +56,11 @@ export class TypescriptEditorPane implements AtomCore.Disposable { this.isTSConfig = basename(this.filePath) === "tsconfig.json" } - clientResolver.get(this.filePath).then(client => { - this.client = client - - this.subscriptions.add(editor.buffer.onDidChange(this.onDidChange)) - this.subscriptions.add(editor.onDidChangeCursorPosition(this.onDidChangeCursorPosition)) - this.subscriptions.add(editor.onDidSave(this.onDidSave)) - this.subscriptions.add(editor.onDidStopChanging(this.onDidStopChanging)) - this.subscriptions.add(editor.onDidDestroy(this.onDidDestroy)) - - if (this.isActive) { - this.opts.statusPanel.setVersion(this.client.version) - } - - if (this.isTypescript && this.filePath) { - this.client.executeOpen({ - file: this.filePath, - fileContent: this.editor.getText() - }) - - 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.setupTooltipView() } dispose() { this.subscriptions.dispose() - - if (this.isOpen) { - this.client.executeClose({file: this.filePath}) - } - this.opts.onDispose(this) } @@ -139,15 +85,22 @@ export class TypescriptEditorPane implements AtomCore.Disposable { this.opts.statusPanel.setTsConfigPath(this.configFile) } + onChanged = () => { + console.warn("changed event") + + this.opts.statusPanel.setBuildStatus(undefined) + + this.client.executeGetErr({ + files: [this.filePath], + delay: 100 + }) + } + onDeactivated = () => { this.isActive = false this.opts.statusPanel.hide() } - onDidChange: onChangeObserver = diff => { - this.changedAt = Date.now() - } - clearOccurrenceMarkers() { for (const marker of this.occurrenceMarkers) { marker.destroy() @@ -192,23 +145,52 @@ export class TypescriptEditorPane implements AtomCore.Disposable { this.dispose() } - onDidSave = async event => { - if (this.filePath !== event.path) { - this.client = await clientResolver.get(event.path) - this.filePath = event.path - this.isTSConfig = basename(this.filePath) === "tsconfig.json" + onOpened = async () => { + console.warn("opened event") + + this.client = await this.opts.getClient(this.filePath) + + this.subscriptions.add(this.editor.onDidChangeCursorPosition(this.onDidChangeCursorPosition)) + this.subscriptions.add(this.editor.onDidDestroy(this.onDidDestroy)) + + if (this.isActive) { + this.opts.statusPanel.setVersion(this.client.version) } - // Check if there isn't a onDidStopChanging event pending. If so, wait for it before updating - if (this.changedAt && this.changedAt > (this.stoppedChangingAt|0)) { - await new Promise(resolve => this.stoppedChangingCallbacks.push(resolve)) + 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 = () => { + console.warn("saved event") if (this.opts.onSave) { this.opts.onSave(this) } this.compileOnSave() + + // if (this.filePath !== event.path) { + // this.client = await this.opts.getClient(event.path) + // this.filePath = event.path + // this.isTSConfig = basename(this.filePath) === "tsconfig.json" + // } } async compileOnSave() { @@ -244,44 +226,6 @@ export class TypescriptEditorPane implements AtomCore.Disposable { } } - onDidStopChanging = ({changes}) => { - this.stoppedChangingAt = Date.now() - - if (this.isTypescript && this.filePath) { - if (this.isOpen) { - - if (changes.length !== 0) { - this.opts.statusPanel.setBuildStatus(undefined) - } - - 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 - } - - this.client.executeChange({ - ...end, - file: this.filePath, - line: start.row + 1, - offset: start.column + 1, - insertString: newText, - }) - } - } - - this.client.executeGetErr({ - files: [this.filePath], - delay: 100 - }) - } - - this.stoppedChangingCallbacks.forEach(fn => fn()) - this.stoppedChangingCallbacks.length = 0 - } - setupTooltipView() { // subscribe for tooltips // inspiration : https://github.com/chaika2013/ide-haskell diff --git a/lib/typings/atom_core.d.ts b/lib/typings/atom_core.d.ts index 3498e4061..f19b31cd0 100644 --- a/lib/typings/atom_core.d.ts +++ b/lib/typings/atom_core.d.ts @@ -10,8 +10,22 @@ declare namespace AtomCore { declare namespace TextBuffer { interface ITextBuffer { + onWillChange(callback: Function): AtomCore.Disposable onDidChange(callback: Function): AtomCore.Disposable - onDidReload(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 } } From 1ba0235aee815ed42f452fcf1c50fbe4cf9fb993 Mon Sep 17 00:00:00 2001 From: Guntars Asmanis-Graham Date: Sun, 8 Jan 2017 16:20:11 -0500 Subject: [PATCH 49/70] =?UTF-8?q?Add=20=E2=80=9CFormat=20Code=E2=80=9D=20c?= =?UTF-8?q?ommand?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- dist/client/client.js | 4 + dist/main/atom/atomUtils.js | 28 ++- dist/main/atom/commands/formatCode.js | 61 ++++++ dist/main/atom/commands/index.js | 28 +-- dist/main/atom/commands/renameRefactor.js | 4 +- dist/main/atomts.js | 22 +-- dist/main/errorPusher.js | 4 +- dist/main/typescriptEditorPane.js | 4 +- dist/main/utils/tsUtil.js | 14 -- lib/client/client.ts | 4 + lib/main/atom/atomUtils.ts | 45 ++++- lib/main/atom/commands/formatCode.ts | 73 +++++++ lib/main/atom/commands/index.ts | 34 +--- lib/main/atom/commands/renameRefactor.ts | 2 +- lib/main/atomts.ts | 228 +++++++++++----------- lib/main/errorPusher.ts | 2 +- lib/main/typescriptEditorPane.ts | 2 +- lib/main/utils/tsUtil.ts | 14 -- lib/typings/typings.d.ts | 6 - 19 files changed, 338 insertions(+), 241 deletions(-) create mode 100644 dist/main/atom/commands/formatCode.js create mode 100644 lib/main/atom/commands/formatCode.ts delete mode 100644 lib/main/utils/tsUtil.ts diff --git a/dist/client/client.js b/dist/client/client.js index dc94eac81..4a4e8be25 100644 --- a/dist/client/client.js +++ b/dist/client/client.js @@ -10,6 +10,7 @@ exports.CommandWithResponse = new Set([ "completionEntryDetails", "completions", "definition", + "format", "occurrences", "projectInfo", "quickinfo", @@ -68,6 +69,9 @@ class TypescriptServiceClient { executeDefinition(args) { return this.execute("definition", args); } + executeFormat(args) { + return this.execute("format", args); + } executeGetErr(args) { return this.execute("geterr", args); } diff --git a/dist/main/atom/atomUtils.js b/dist/main/atom/atomUtils.js index b446099dc..30d04d0d6 100644 --- a/dist/main/atom/atomUtils.js +++ b/dist/main/atom/atomUtils.js @@ -5,6 +5,28 @@ const fs = require("fs"); const fsu = require("../utils/fsUtil"); const path = require("path"); const url = require("url"); +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; // Return line/offset position in the editor using 1-indexed coordinates function getEditorPosition(editor) { const pos = editor.getCursorBufferPosition(); @@ -128,9 +150,9 @@ function quickNotifyWarning(htmlMessage) { } 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(spanToRange(edits[i]), edits[i].newText); } } exports.formatCode = formatCode; diff --git a/dist/main/atom/commands/formatCode.js b/dist/main/atom/commands/formatCode.js new file mode 100644 index 000000000..fd6803b02 --- /dev/null +++ b/dist/main/atom/commands/formatCode.js @@ -0,0 +1,61 @@ +"use strict"; +const tslib_1 = require("tslib"); +const registry_1 = require("./registry"); +const atomUtils_1 = require("../atomUtils"); +registry_1.commands.set("typescript:format-code", deps => { + return (e) => tslib_1.__awaiter(this, void 0, void 0, function* () { + if (!atomUtils_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(atomUtils_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 edits = []; + // Collect all edits together so we can update in a single transaction + for (const range of ranges) { + const result = yield client.executeFormat(tslib_1.__assign({}, range, { file: filePath })); + if (result.body) { + edits.push(...result.body); + } + } + if (edits.length > 0) { + editor.transact(() => { + atomUtils_1.formatCode(editor, edits); + }); + } + // if (selection.isEmpty()) { + // console.log("no selection, format all") + // parent.formatDocument({ filePath: filePath }).then((result) => { + // if (!result.edits.length) return; + // editor.transact(() => { + // atomUtils.formatCode(editor, result.edits); + // }); + // }); + // } else { + // console.log("selcetion", selection, filePath) + // + // 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); + // }); + // }); + // } + }); +}); diff --git a/dist/main/atom/commands/index.js b/dist/main/atom/commands/index.js index 9b6e92243..c11a7cb90 100644 --- a/dist/main/atom/commands/index.js +++ b/dist/main/atom/commands/index.js @@ -16,6 +16,7 @@ const registry_1 = require("./registry"); require("./build"); require("./checkAllFiles"); require("./clearErrors"); +require("./formatCode"); require("./findReferences"); require("./goToDeclaration"); require("./renameRefactor"); @@ -23,28 +24,6 @@ function registerCommands(deps) { for (const [name, command] of registry_1.commands) { atom.commands.add("atom-workspace", name, command(deps)); } - // 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:create-tsconfig.json-project-file', (e) => { // if (!atomUtils.commandForTypeScript(e)) return; // var editor = atom.workspace.getActiveTextEditor(); @@ -127,10 +106,5 @@ function registerCommands(deps) { // theProjectSymbolsView.show(); // }); // }, 400); - atom.commands.add('atom-workspace', 'typescript:sync', (e) => { - console.log("typescript:sync trigerred"); - // if (!atomUtils.commandForTypeScript(e)) return; - // panelView.softReset(); - }); } exports.registerCommands = registerCommands; diff --git a/dist/main/atom/commands/renameRefactor.js b/dist/main/atom/commands/renameRefactor.js index e742c59ef..a669e2261 100644 --- a/dist/main/atom/commands/renameRefactor.js +++ b/dist/main/atom/commands/renameRefactor.js @@ -2,7 +2,7 @@ const tslib_1 = require("tslib"); const registry_1 = require("./registry"); const atomUtils_1 = require("../atomUtils"); -const tsUtil_1 = require("./../../utils/tsUtil"); +const atomUtils_2 = require("../atomUtils"); registry_1.commands.set("typescript:rename-refactor", deps => { return (e) => tslib_1.__awaiter(this, void 0, void 0, function* () { if (!atomUtils_1.commandForTypeScript(e)) { @@ -33,7 +33,7 @@ registry_1.commands.set("typescript:rename-refactor", deps => { const { buffer, isOpen } = yield deps.getBuffer(loc.file); buffer.transact(() => { for (const span of loc.locs) { - buffer.setTextInRange(tsUtil_1.spanToRange(span), newName); + buffer.setTextInRange(atomUtils_2.spanToRange(span), newName); } }); if (!isOpen) { diff --git a/dist/main/atomts.js b/dist/main/atomts.js index d2b3bd593..25c48a7a7 100644 --- a/dist/main/atomts.js +++ b/dist/main/atomts.js @@ -2,22 +2,22 @@ const tslib_1 = require("tslib"); // import {getFileStatus} from "./atom/fileStatusCache" // import {$} from "atom-space-pen-views" -const clientResolver_1 = require("../client/clientResolver"); -const atom_1 = require("atom"); -const lodash_1 = require("lodash"); -const errorPusher_1 = require("./errorPusher"); -const typescriptEditorPane_1 = require("./typescriptEditorPane"); -const statusPanel_1 = require("./atom/components/statusPanel"); -const atomConfig = require("./atom/atomConfig"); // import * as atomUtils from './atom/atomUtils' -const autoCompleteProvider_1 = require("./atom/autoCompleteProvider"); // import * as fs from 'fs' -const hyperclickProvider = require("../hyperclickProvider"); // import * as path from 'path' -const renameView_1 = require("./atom/views/renameView"); +const Atom = require("atom"); +const atomConfig = require("./atom/atomConfig"); +const hyperclickProvider = require("../hyperclickProvider"); 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 Atom = require("atom"); +const statusPanel_1 = require("./atom/components/statusPanel"); +const typescriptEditorPane_1 = require("./typescriptEditorPane"); // globals const subscriptions = new atom_1.CompositeDisposable(); exports.clientResolver = new clientResolver_1.ClientResolver(); diff --git a/dist/main/errorPusher.js b/dist/main/errorPusher.js index 202529321..7906ff0df 100644 --- a/dist/main/errorPusher.js +++ b/dist/main/errorPusher.js @@ -1,6 +1,6 @@ "use strict"; const lodash_1 = require("lodash"); -const tsUtil_1 = require("./utils/tsUtil"); +const atomUtils_1 = require("./atom/atomUtils"); /** Class that collects errors from all of the clients and pushes them to the Linter service */ class ErrorPusher { constructor() { @@ -14,7 +14,7 @@ class ErrorPusher { type: "Error", text: diagnostic.text, filePath: filePath, - range: diagnostic.start ? tsUtil_1.locationsToRange(diagnostic.start, diagnostic.end) : undefined + range: diagnostic.start ? atomUtils_1.locationsToRange(diagnostic.start, diagnostic.end) : undefined }); } } diff --git a/dist/main/typescriptEditorPane.js b/dist/main/typescriptEditorPane.js index b722bc062..133fee1e3 100644 --- a/dist/main/typescriptEditorPane.js +++ b/dist/main/typescriptEditorPane.js @@ -4,7 +4,7 @@ const atom_space_pen_views_1 = require("atom-space-pen-views"); const path_1 = require("path"); const atom_1 = require("atom"); const lodash_1 = require("lodash"); -const tsUtil_1 = require("./utils/tsUtil"); +const atomUtils_1 = require("./atom/atomUtils"); const typescriptBuffer_1 = require("./typescriptBuffer"); const tooltipManager = require("./atom/tooltipManager"); class TypescriptEditorPane { @@ -54,7 +54,7 @@ class TypescriptEditorPane { }).then(result => { this.clearOccurrenceMarkers(); for (const ref of result.body) { - const marker = this.editor.markBufferRange(tsUtil_1.spanToRange(ref)); + const marker = this.editor.markBufferRange(atomUtils_1.spanToRange(ref)); this.editor.decorateMarker(marker, { type: "highlight", class: "atom-typescript-occurrence" diff --git a/dist/main/utils/tsUtil.js b/dist/main/utils/tsUtil.js index fe4b817c3..e69de29bb 100644 --- a/dist/main/utils/tsUtil.js +++ b/dist/main/utils/tsUtil.js @@ -1,14 +0,0 @@ -"use strict"; -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; diff --git a/lib/client/client.ts b/lib/client/client.ts index 85b45ed94..8fb7eb938 100644 --- a/lib/client/client.ts +++ b/lib/client/client.ts @@ -10,6 +10,7 @@ export const CommandWithResponse = new Set([ "completionEntryDetails", "completions", "definition", + "format", "occurrences", "projectInfo", "quickinfo", @@ -70,6 +71,9 @@ export class TypescriptServiceClient { 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) } diff --git a/lib/main/atom/atomUtils.ts b/lib/main/atom/atomUtils.ts index 9916c62de..e8eac9c31 100644 --- a/lib/main/atom/atomUtils.ts +++ b/lib/main/atom/atomUtils.ts @@ -3,16 +3,46 @@ import * as fs from "fs" import * as fsu from "../utils/fsUtil" import * as path from "path" import * as url from "url" +import {TextSpan, CodeEdit} from "typescript/lib/protocol" +import {Point, Range} from "atom" + +export {TextSpan, CodeEdit} 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, end): 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 + } +} + // Return line/offset position in the editor using 1-indexed coordinates export function getEditorPosition(editor: AtomCore.IEditor): LocationQuery { const pos = editor.getCursorBufferPosition() @@ -37,6 +67,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(); @@ -142,17 +173,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) { diff --git a/lib/main/atom/commands/formatCode.ts b/lib/main/atom/commands/formatCode.ts new file mode 100644 index 000000000..332b30e61 --- /dev/null +++ b/lib/main/atom/commands/formatCode.ts @@ -0,0 +1,73 @@ +import {commands} from "./registry" +import { + commandForTypeScript, + LocationRangeQuery, + rangeToLocationRange, + formatCode, + CodeEdit +} from "../atomUtils" + +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 edits: CodeEdit[] = [] + + // Collect all edits together so we can update in a single transaction + for (const range of ranges) { + const result = await client.executeFormat({...range, file: filePath}) + if (result.body) { + edits.push(...result.body) + } + } + + if (edits.length > 0) { + editor.transact(() => { + formatCode(editor, edits) + }) + } + + // if (selection.isEmpty()) { + // console.log("no selection, format all") + // parent.formatDocument({ filePath: filePath }).then((result) => { + // if (!result.edits.length) return; + // editor.transact(() => { + // atomUtils.formatCode(editor, result.edits); + // }); + // }); + // } else { + // console.log("selcetion", selection, filePath) + // + // 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); + // }); + // }); + // } + } +}) diff --git a/lib/main/atom/commands/index.ts b/lib/main/atom/commands/index.ts index 3bb4dc8bc..6c9ac4293 100644 --- a/lib/main/atom/commands/index.ts +++ b/lib/main/atom/commands/index.ts @@ -18,6 +18,7 @@ import {commands, Dependencies} from "./registry" import "./build" import "./checkAllFiles" import "./clearErrors" +import "./formatCode" import "./findReferences" import "./goToDeclaration" import "./renameRefactor" @@ -28,31 +29,6 @@ export function registerCommands(deps: Dependencies) { atom.commands.add("atom-workspace", name, command(deps)) } - // 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:create-tsconfig.json-project-file', (e) => { // if (!atomUtils.commandForTypeScript(e)) return; @@ -146,12 +122,4 @@ export function registerCommands(deps: Dependencies) { // theProjectSymbolsView.show(); // }); // }, 400); - - atom.commands.add('atom-workspace', 'typescript:sync', (e) => { - console.log("typescript:sync trigerred") - - // if (!atomUtils.commandForTypeScript(e)) return; - // panelView.softReset(); - }); - } diff --git a/lib/main/atom/commands/renameRefactor.ts b/lib/main/atom/commands/renameRefactor.ts index 5c8458494..a09b0992f 100644 --- a/lib/main/atom/commands/renameRefactor.ts +++ b/lib/main/atom/commands/renameRefactor.ts @@ -1,6 +1,6 @@ import {commands} from "./registry" import {commandForTypeScript, getFilePathPosition} from "../atomUtils" -import {spanToRange} from "./../../utils/tsUtil" +import {spanToRange} from "../atomUtils" commands.set("typescript:rename-refactor", deps => { return async e => { diff --git a/lib/main/atomts.ts b/lib/main/atomts.ts index 5eff72b89..2ded36add 100644 --- a/lib/main/atomts.ts +++ b/lib/main/atomts.ts @@ -1,23 +1,23 @@ // import {getFileStatus} from "./atom/fileStatusCache" // import {$} from "atom-space-pen-views" +// import * as atomUtils from './atom/atomUtils' +// import * as fs from 'fs' +// import * as path from 'path' +import * as Atom from "atom" +import * as atomConfig from './atom/atomConfig' +import * as hyperclickProvider from "../hyperclickProvider" +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 {TypescriptEditorPane} from "./typescriptEditorPane" import {StatusPanel} from "./atom/components/statusPanel" -import * as atomConfig from './atom/atomConfig' -// import * as atomUtils from './atom/atomUtils' -import {AutocompleteProvider} from './atom/autoCompleteProvider' -// import * as fs from 'fs' -import * as hyperclickProvider from "../hyperclickProvider" -// import * as path from 'path' -import {attach as attachRenameView} from './atom/views/renameView' -import * as tsconfig from "tsconfig/dist/tsconfig" -import {flatten, values} from "lodash" -import * as Atom from "atom" +import {TypescriptEditorPane} from "./typescriptEditorPane" // globals const subscriptions = new CompositeDisposable() @@ -34,139 +34,139 @@ let statusBar: StatusBar interface PackageState {} export function activate(state: PackageState) { - require('atom-package-deps').install('atom-typescript').then(() => { + require('atom-package-deps').install('atom-typescript').then(() => { - let statusPriority = 100 - for (const panel of statusBar.getRightTiles()) { - if (panel.getItem().tagName === "GRAMMAR-SELECTOR-STATUS") { - statusPriority = panel.getPriority() - 1 - } + let statusPriority = 100 + for (const panel of statusBar.getRightTiles()) { + if (panel.getItem().tagName === "GRAMMAR-SELECTOR-STATUS") { + statusPriority = panel.getPriority() - 1 } + } - // Add the rename view - const {renameView} = attachRenameView() - const statusPanel = StatusPanel.create() + // Add the rename view + const {renameView} = attachRenameView() + const statusPanel = StatusPanel.create() - statusBar.addRightTile({ - item: statusPanel, - priority: statusPriority - }) + statusBar.addRightTile({ + item: statusPanel, + priority: statusPriority + }) - subscriptions.add(statusPanel) + subscriptions.add(statusPanel) - const errorPusher = new ErrorPusher() + const errorPusher = new ErrorPusher() - clientResolver.on("pendingRequestsChange", () => { - const pending = flatten(values(clientResolver.clients).map(cl => cl.pending)) - statusPanel.setPending(pending) - }) + clientResolver.on("pendingRequestsChange", () => { + const pending = flatten(values(clientResolver.clients).map(cl => cl.pending)) + statusPanel.setPending(pending) + }) - if (linter) { - errorPusher.setLinter(linter) + if (linter) { + errorPusher.setLinter(linter) - clientResolver.on("diagnostics", ({type, filePath, diagnostics}) => { - errorPusher.setErrors(type, filePath, diagnostics) - }) - } - - // Register the commands - registerCommands({ - clearErrors() { - errorPusher.clear() - }, - async getBuffer(filePath: string) { - const pane = panes.find(pane => pane.filePath === filePath) - if (pane) { - return { - buffer: pane.editor.buffer, - isOpen: true - } + clientResolver.on("diagnostics", ({type, filePath, diagnostics}) => { + errorPusher.setErrors(type, filePath, diagnostics) + }) + } + + // Register the commands + registerCommands({ + clearErrors() { + errorPusher.clear() + }, + async getBuffer(filePath: string) { + const pane = panes.find(pane => pane.filePath === filePath) + if (pane) { + return { + buffer: pane.editor.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 - }) + // 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) - }) + buffer.onDidReload(() => { + resolve(buffer) }) + }) - return { - buffer, - isOpen: false - } - }, - async getClient(filePath: string) { - const pane = panes.find(pane => pane.filePath === filePath) - if (pane) { - return pane.client - } + return { + buffer, + isOpen: false + } + }, + async getClient(filePath: string) { + const pane = panes.find(pane => pane.filePath === filePath) + if (pane) { + return pane.client + } - return clientResolver.get(filePath) - }, - renameView, - statusPanel, - }) + return clientResolver.get(filePath) + }, + renameView, + statusPanel, + }) - let activePane: TypescriptEditorPane | undefined - const panes: TypescriptEditorPane[] = [] + let activePane: TypescriptEditorPane | undefined + const panes: TypescriptEditorPane[] = [] - const onSave = debounce((pane: TypescriptEditorPane) => { - console.log("checking errors for all panes for", pane.filePath) + const onSave = debounce((pane: TypescriptEditorPane) => { + console.log("checking errors for all panes for", pane.filePath) - const files = panes - .sort((a, b) => a.activeAt - b.activeAt) - .filter(_pane => _pane.filePath && _pane.isTypescript && _pane.client === pane.client) - .map(pane => pane.filePath) + 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}) + pane.client.executeGetErr({files, delay: 100}) - }, 50) + }, 50) - 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 - } + 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) + 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, - })) + // Clear errors if any from this pane + errorPusher.setErrors("syntaxDiag", pane.filePath, []) + errorPusher.setErrors("semanticDiag", pane.filePath, []) + }, + onSave, + statusPanel, })) + })) + + panes.find(pane => pane.editor === atom.workspace.getActiveTextEditor()) - panes.find(pane => pane.editor === atom.workspace.getActiveTextEditor()) + if (activePane) { + activePane.onActivated() + } + subscriptions.add(atom.workspace.onDidChangeActivePaneItem((editor: AtomCore.IEditor) => { if (activePane) { - activePane.onActivated() + activePane.onDeactivated() + activePane = undefined } - 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() } - - if (atom.workspace.isTextEditor(editor)) { - const pane = panes.find(pane => pane.editor === editor) - if (pane) { - activePane = pane - pane.onActivated() - } - } - })) - }) + } + })) + }) } export function deactivate() { diff --git a/lib/main/errorPusher.ts b/lib/main/errorPusher.ts index 14e1f2b97..83b474aef 100644 --- a/lib/main/errorPusher.ts +++ b/lib/main/errorPusher.ts @@ -1,7 +1,7 @@ import {debounce} from "lodash" import {Diagnostic} from "typescript/lib/protocol" import {Linter, LinterMessage} from "../typings/linter" -import {locationsToRange} from "./utils/tsUtil" +import {locationsToRange} from "./atom/atomUtils" /** Class that collects errors from all of the clients and pushes them to the Linter service */ export class ErrorPusher { diff --git a/lib/main/typescriptEditorPane.ts b/lib/main/typescriptEditorPane.ts index a5b301408..673e3825a 100644 --- a/lib/main/typescriptEditorPane.ts +++ b/lib/main/typescriptEditorPane.ts @@ -2,7 +2,7 @@ import {$} from "atom-space-pen-views" import {basename} from "path" import {CompositeDisposable} from "atom" import {debounce, flatten} from "lodash" -import {spanToRange} from "./utils/tsUtil" +import {spanToRange} from "./atom/atomUtils" import {TypescriptServiceClient} from "../client/client" import {TypescriptBuffer} from "./typescriptBuffer" import {StatusPanel} from "./atom/components/statusPanel" diff --git a/lib/main/utils/tsUtil.ts b/lib/main/utils/tsUtil.ts deleted file mode 100644 index 1213d91b4..000000000 --- a/lib/main/utils/tsUtil.ts +++ /dev/null @@ -1,14 +0,0 @@ -import {Location, TextSpan} from "typescript/lib/protocol" -import {Point, Range} from "atom" - -export function locationToPoint(loc: Location): 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, end): TextBuffer.IRange { - return new Range(locationToPoint(start), locationToPoint(end)) -} diff --git a/lib/typings/typings.d.ts b/lib/typings/typings.d.ts index 41c756c6b..c0d18a10b 100644 --- a/lib/typings/typings.d.ts +++ b/lib/typings/typings.d.ts @@ -82,12 +82,6 @@ interface EditorPosition { col: number; } -interface CodeEdit { - start: EditorPosition; - end: EditorPosition; - newText: string; -} - /** Interfaces used by GotoHistory feature */ interface GotoPosition { filePath: string; From 698abd6463a2455026b4750dac256bac72f7ddd3 Mon Sep 17 00:00:00 2001 From: Guntars Asmanis-Graham Date: Sun, 8 Jan 2017 16:36:35 -0500 Subject: [PATCH 50/70] Organize the utils a little --- dist/main/atom/autoCompleteProvider.js | 4 +- dist/main/atom/commands/build.js | 6 +- dist/main/atom/commands/checkAllFiles.js | 6 +- dist/main/atom/commands/findReferences.js | 6 +- dist/main/atom/commands/formatCode.js | 8 +- dist/main/atom/commands/goToDeclaration.js | 6 +- dist/main/atom/commands/index.js | 2 +- dist/main/atom/commands/renameRefactor.js | 10 +- dist/main/atom/components/statusPanel.js | 6 +- dist/main/atom/fileStatusCache.js | 16 - dist/main/atom/tooltipManager.js | 2 +- .../main/atom/{atomUtils.js => utils/atom.js} | 34 +- dist/main/atom/utils/fs.js | 33 ++ dist/main/atom/utils/index.js | 7 + dist/main/atom/utils/ts.js | 23 ++ dist/main/atom/views/fileSymbolsView.js | 54 --- dist/main/atom/views/mainPanelView.js | 352 ------------------ dist/main/atom/views/projectSymbolsView.js | 60 --- dist/main/atomts.js | 2 +- dist/main/errorPusher.js | 4 +- dist/main/typescriptBuffer.js | 4 +- dist/main/typescriptEditorPane.js | 4 +- dist/main/utils/fsUtil.js | 33 -- dist/main/utils/tsUtil.js | 0 lib/main/atom/autoCompleteProvider.ts | 2 +- lib/main/atom/commands/build.ts | 2 +- lib/main/atom/commands/checkAllFiles.ts | 2 +- lib/main/atom/commands/findReferences.ts | 2 +- lib/main/atom/commands/formatCode.ts | 2 +- lib/main/atom/commands/goToDeclaration.ts | 2 +- lib/main/atom/commands/index.ts | 2 +- lib/main/atom/commands/renameRefactor.ts | 4 +- lib/main/atom/components/statusPanel.tsx | 2 +- lib/main/atom/fileStatusCache.ts | 21 -- lib/main/atom/tooltipManager.ts | 2 +- lib/main/atom/{atomUtils.ts => utils/atom.ts} | 55 +-- lib/main/atom/utils/fs.ts | 33 ++ lib/main/atom/utils/index.ts | 3 + lib/main/atom/utils/ts.ts | 39 ++ lib/main/atomts.ts | 2 +- lib/main/errorPusher.ts | 2 +- lib/main/typescriptBuffer.ts | 2 +- lib/main/typescriptEditorPane.ts | 2 +- lib/main/utils/fsUtil.ts | 33 -- 44 files changed, 205 insertions(+), 691 deletions(-) delete mode 100644 dist/main/atom/fileStatusCache.js rename dist/main/atom/{atomUtils.js => utils/atom.js} (89%) create mode 100644 dist/main/atom/utils/fs.js create mode 100644 dist/main/atom/utils/index.js create mode 100644 dist/main/atom/utils/ts.js delete mode 100644 dist/main/atom/views/fileSymbolsView.js delete mode 100644 dist/main/atom/views/mainPanelView.js delete mode 100644 dist/main/atom/views/projectSymbolsView.js delete mode 100644 dist/main/utils/tsUtil.js delete mode 100644 lib/main/atom/fileStatusCache.ts rename lib/main/atom/{atomUtils.ts => utils/atom.ts} (87%) create mode 100644 lib/main/atom/utils/fs.ts create mode 100644 lib/main/atom/utils/index.ts create mode 100644 lib/main/atom/utils/ts.ts diff --git a/dist/main/atom/autoCompleteProvider.js b/dist/main/atom/autoCompleteProvider.js index 00c143f60..7d8d9c5f6 100644 --- a/dist/main/atom/autoCompleteProvider.js +++ b/dist/main/atom/autoCompleteProvider.js @@ -1,6 +1,6 @@ "use strict"; const tslib_1 = require("tslib"); -const atomUtils_1 = require("./atomUtils"); +const utils_1 = require("./utils"); const fuzzaldrin = require("fuzzaldrin"); class AutocompleteProvider { constructor(clientResolver) { @@ -32,7 +32,7 @@ class AutocompleteProvider { const suggestions = completions.body.map(entry => ({ text: entry.name, leftLabel: entry.kind, - type: atomUtils_1.kindToType(entry.kind), + type: utils_1.kindToType(entry.kind), })); this.lastSuggestions = { client, diff --git a/dist/main/atom/commands/build.js b/dist/main/atom/commands/build.js index 0e554d834..827a32184 100644 --- a/dist/main/atom/commands/build.js +++ b/dist/main/atom/commands/build.js @@ -1,13 +1,13 @@ "use strict"; const tslib_1 = require("tslib"); const registry_1 = require("./registry"); -const atomUtils_1 = require("../atomUtils"); +const utils_1 = require("../utils"); registry_1.commands.set("typescript:build", deps => { return (e) => tslib_1.__awaiter(this, void 0, void 0, function* () { - if (!atomUtils_1.commandForTypeScript(e)) { + if (!utils_1.commandForTypeScript(e)) { return; } - const { file } = atomUtils_1.getFilePathPosition(); + const { file } = utils_1.getFilePathPosition(); const client = yield deps.getClient(file); const projectInfo = yield client.executeProjectInfo({ file, diff --git a/dist/main/atom/commands/checkAllFiles.js b/dist/main/atom/commands/checkAllFiles.js index 5f40dfc76..3f1bc58eb 100644 --- a/dist/main/atom/commands/checkAllFiles.js +++ b/dist/main/atom/commands/checkAllFiles.js @@ -1,13 +1,13 @@ "use strict"; const tslib_1 = require("tslib"); const registry_1 = require("./registry"); -const atomUtils_1 = require("../atomUtils"); +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 (!atomUtils_1.commandForTypeScript(e)) { + if (!utils_1.commandForTypeScript(e)) { return; } - const { file } = atomUtils_1.getFilePathPosition(); + const { file } = utils_1.getFilePathPosition(); const client = yield deps.getClient(file); const projectInfo = yield client.executeProjectInfo({ file, diff --git a/dist/main/atom/commands/findReferences.js b/dist/main/atom/commands/findReferences.js index 0a9bf04a8..3d7af00aa 100644 --- a/dist/main/atom/commands/findReferences.js +++ b/dist/main/atom/commands/findReferences.js @@ -1,15 +1,15 @@ "use strict"; const tslib_1 = require("tslib"); const registry_1 = require("./registry"); -const atomUtils_1 = require("../atomUtils"); +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 (!atomUtils_1.commandForTypeScript(e)) { + if (!utils_1.commandForTypeScript(e)) { return; } - const location = atomUtils_1.getFilePathPosition(); + const location = utils_1.getFilePathPosition(); const client = yield deps.getClient(location.file); const result = yield client.executeReferences(location); simpleSelectionView_1.simpleSelectionView({ diff --git a/dist/main/atom/commands/formatCode.js b/dist/main/atom/commands/formatCode.js index fd6803b02..68ad4713e 100644 --- a/dist/main/atom/commands/formatCode.js +++ b/dist/main/atom/commands/formatCode.js @@ -1,10 +1,10 @@ "use strict"; const tslib_1 = require("tslib"); const registry_1 = require("./registry"); -const atomUtils_1 = require("../atomUtils"); +const utils_1 = require("../utils"); registry_1.commands.set("typescript:format-code", deps => { return (e) => tslib_1.__awaiter(this, void 0, void 0, function* () { - if (!atomUtils_1.commandForTypeScript(e)) { + if (!utils_1.commandForTypeScript(e)) { return; } const editor = atom.workspace.getActiveTextEditor(); @@ -12,7 +12,7 @@ registry_1.commands.set("typescript:format-code", deps => { const ranges = []; for (const selection of editor.getSelectedBufferRanges()) { if (!selection.isEmpty()) { - ranges.push(atomUtils_1.rangeToLocationRange(selection)); + ranges.push(utils_1.rangeToLocationRange(selection)); } } // Format the whole document if there are no ranges added @@ -36,7 +36,7 @@ registry_1.commands.set("typescript:format-code", deps => { } if (edits.length > 0) { editor.transact(() => { - atomUtils_1.formatCode(editor, edits); + utils_1.formatCode(editor, edits); }); } // if (selection.isEmpty()) { diff --git a/dist/main/atom/commands/goToDeclaration.js b/dist/main/atom/commands/goToDeclaration.js index 44bff02da..d757995fc 100644 --- a/dist/main/atom/commands/goToDeclaration.js +++ b/dist/main/atom/commands/goToDeclaration.js @@ -1,14 +1,14 @@ "use strict"; const tslib_1 = require("tslib"); const registry_1 = require("./registry"); -const atomUtils_1 = require("../atomUtils"); +const utils_1 = require("../utils"); const simpleSelectionView_1 = require("../views/simpleSelectionView"); registry_1.commands.set("typescript:go-to-declaration", deps => { return (e) => tslib_1.__awaiter(this, void 0, void 0, function* () { - if (!atomUtils_1.commandForTypeScript(e)) { + if (!utils_1.commandForTypeScript(e)) { return; } - const location = atomUtils_1.getFilePathPosition(); + const location = utils_1.getFilePathPosition(); const client = yield deps.getClient(location.file); const result = yield client.executeDefinition(location); if (result.body.length > 1) { diff --git a/dist/main/atom/commands/index.js b/dist/main/atom/commands/index.js index c11a7cb90..dcd56af91 100644 --- a/dist/main/atom/commands/index.js +++ b/dist/main/atom/commands/index.js @@ -1,4 +1,4 @@ -// import atomUtils = require("../atomUtils"); +// import atomUtils = require("../utils"); // import path = require('path'); // import renameView = require("../views/renameView"); // import fileSymbolsView = require("../views/fileSymbolsView"); diff --git a/dist/main/atom/commands/renameRefactor.js b/dist/main/atom/commands/renameRefactor.js index a669e2261..7f4904281 100644 --- a/dist/main/atom/commands/renameRefactor.js +++ b/dist/main/atom/commands/renameRefactor.js @@ -1,14 +1,14 @@ "use strict"; const tslib_1 = require("tslib"); const registry_1 = require("./registry"); -const atomUtils_1 = require("../atomUtils"); -const atomUtils_2 = require("../atomUtils"); +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 (!atomUtils_1.commandForTypeScript(e)) { + if (!utils_1.commandForTypeScript(e)) { return; } - const location = atomUtils_1.getFilePathPosition(); + const location = utils_1.getFilePathPosition(); const client = yield deps.getClient(location.file); const response = yield client.executeRename(location); const { info, locs } = response.body; @@ -33,7 +33,7 @@ registry_1.commands.set("typescript:rename-refactor", deps => { const { buffer, isOpen } = yield deps.getBuffer(loc.file); buffer.transact(() => { for (const span of loc.locs) { - buffer.setTextInRange(atomUtils_2.spanToRange(span), newName); + buffer.setTextInRange(utils_2.spanToRange(span), newName); } }); if (!isOpen) { diff --git a/dist/main/atom/components/statusPanel.js b/dist/main/atom/components/statusPanel.js index d4ec53dbb..6db5dfa02 100644 --- a/dist/main/atom/components/statusPanel.js +++ b/dist/main/atom/components/statusPanel.js @@ -1,7 +1,7 @@ "use strict"; const dom = require("jsx-render-dom"); const path_1 = require("path"); -const atomUtils_1 = require("../atomUtils"); +const utils_1 = require("../utils"); class StatusPanel extends HTMLElement { createdCallback() { const nodes = [ @@ -34,7 +34,7 @@ class StatusPanel extends HTMLElement { } openConfigPath() { if (this.configPath && !this.configPath.startsWith("/dev/null")) { - atomUtils_1.openFile(this.configPath); + utils_1.openFile(this.configPath); } else { atom.notifications.addInfo("No tsconfig for current file"); @@ -73,7 +73,7 @@ class StatusPanel extends HTMLElement { this.configPath = configPath; if (configPath) { this.configPathContainer.textContent = configPath.startsWith("/dev/null") ? "No project" : - path_1.dirname(atomUtils_1.getFilePathRelativeToAtomProject(configPath)); + path_1.dirname(utils_1.getFilePathRelativeToAtomProject(configPath)); this.configPathContainer.classList.remove("hide"); } else { diff --git a/dist/main/atom/fileStatusCache.js b/dist/main/atom/fileStatusCache.js deleted file mode 100644 index 3a18a94b2..000000000 --- a/dist/main/atom/fileStatusCache.js +++ /dev/null @@ -1,16 +0,0 @@ -"use strict"; -/** - * We keep an in memory cache of certain knowledge points regarding a few file paths - * This file maintains that - */ -const fsUtil_1 = require("../utils/fsUtil"); -; -let 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/tooltipManager.js b/dist/main/atom/tooltipManager.js index cf9554af8..533ff91d8 100644 --- a/dist/main/atom/tooltipManager.js +++ b/dist/main/atom/tooltipManager.js @@ -2,7 +2,7 @@ // and https://atom.io/packages/ide-flow "use strict"; const tslib_1 = require("tslib"); -const atomUtils = require("./atomUtils"); ///ts:import:generated +const atomUtils = require("./utils"); ///ts:import:generated const atomts_1 = require("../atomts"); const path = require("path"); const fs = require("fs"); diff --git a/dist/main/atom/atomUtils.js b/dist/main/atom/utils/atom.js similarity index 89% rename from dist/main/atom/atomUtils.js rename to dist/main/atom/utils/atom.js index 30d04d0d6..14d9ca3a4 100644 --- a/dist/main/atom/atomUtils.js +++ b/dist/main/atom/utils/atom.js @@ -2,31 +2,9 @@ const tslib_1 = require("tslib"); const Atom = require("atom"); const fs = require("fs"); -const fsu = require("../utils/fsUtil"); const path = require("path"); const url = require("url"); -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; +const _1 = require("./"); // Return line/offset position in the editor using 1-indexed coordinates function getEditorPosition(editor) { const pos = editor.getCursorBufferPosition(); @@ -103,7 +81,7 @@ function getEditorsForAllPaths(filePaths) { var map = {}; 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); /// find the editors that are not in here @@ -132,7 +110,7 @@ function getTypeScriptEditorsWithPaths() { } exports.getTypeScriptEditorsWithPaths = getTypeScriptEditorsWithPaths; function getOpenTypeScritEditorsConsistentPaths() { - return getTypeScriptEditorsWithPaths().map(e => fsu.consistentPath(e.getPath())); + return getTypeScriptEditorsWithPaths().map(e => _1.consistentPath(e.getPath())); } exports.getOpenTypeScritEditorsConsistentPaths = getOpenTypeScritEditorsConsistentPaths; function quickNotifySuccess(htmlMessage) { @@ -152,7 +130,7 @@ exports.quickNotifyWarning = quickNotifyWarning; function formatCode(editor, edits) { // 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); + editor.setTextInBufferRange(_1.spanToRange(edits[i]), edits[i].newText); } } exports.formatCode = formatCode; @@ -212,7 +190,7 @@ 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 = { @@ -279,7 +257,7 @@ 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); diff --git a/dist/main/atom/utils/fs.js b/dist/main/atom/utils/fs.js new file mode 100644 index 000000000..f691f5e28 --- /dev/null +++ b/dist/main/atom/utils/fs.js @@ -0,0 +1,33 @@ +/** + * Wraps fs and path into a nice "consistentPath" API + */ +"use strict"; +/** we work with "/" for all paths (so does the typescript language service) */ +function consistentPath(filePath) { + return filePath.split('\\').join('/'); +} +exports.consistentPath = consistentPath; +const path = require("path"); +/** + * 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; diff --git a/dist/main/atom/utils/index.js b/dist/main/atom/utils/index.js new file mode 100644 index 000000000..bad9d14c2 --- /dev/null +++ b/dist/main/atom/utils/index.js @@ -0,0 +1,7 @@ +"use strict"; +function __export(m) { + for (var p in m) if (!exports.hasOwnProperty(p)) exports[p] = m[p]; +} +__export(require("./atom")); +__export(require("./fs")); +__export(require("./ts")); diff --git a/dist/main/atom/utils/ts.js b/dist/main/atom/utils/ts.js new file mode 100644 index 000000000..8709128e3 --- /dev/null +++ b/dist/main/atom/utils/ts.js @@ -0,0 +1,23 @@ +"use strict"; +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; diff --git a/dist/main/atom/views/fileSymbolsView.js b/dist/main/atom/views/fileSymbolsView.js deleted file mode 100644 index bc6c6fd8d..000000000 --- a/dist/main/atom/views/fileSymbolsView.js +++ /dev/null @@ -1,54 +0,0 @@ -"use strict"; -const sp = require("atom-space-pen-views"); -const atomUtils = require("../atomUtils"); -/** - * https://github.com/atom/atom-space-pen-views - */ -class FileSymbolsView extends sp.SelectListView { - constructor() { - super(...arguments); - this.panel = null; - } - get $() { - return this; - } - setNavBarItems(tsItems, filePath) { - var items = tsItems; - this.filePath = filePath; - super.setItems(items); - } - /** override */ - viewForItem(item) { - return ` -
  • -
    ${Array(item.indent * 2).join(' ') + (item.indent ? "\u221F " : '') + item.text}
    -
    ${item.kind}
    -
    line: ${item.position.line + 1}
    -
  • - `; - } - /** override */ - confirmed(item) { - atom.workspace.open(this.filePath, { - initialLine: item.position.line, - initialColumn: item.position.col - }); - this.hide(); - } - getFilterKey() { return 'text'; } - 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(); - } -} -exports.FileSymbolsView = FileSymbolsView; diff --git a/dist/main/atom/views/mainPanelView.js b/dist/main/atom/views/mainPanelView.js deleted file mode 100644 index bb159dca4..000000000 --- a/dist/main/atom/views/mainPanelView.js +++ /dev/null @@ -1,352 +0,0 @@ -"use strict"; -const view = require("./view"); -const lineMessageView = require("./lineMessageView"); -const atomUtils = require("../atomUtils"); -const panelHeaders = { - build: 'Last Build Output', - references: 'References' -}; -const gotoHistory = require("../gotoHistory"); -class MainPanelView extends view.View { - constructor() { - super(...arguments); - this.pendingRequests = []; - this.expanded = false; - } - static content() { - var btn = (view, text, className = '') => 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('build', panelHeaders.build, 'selected'); - 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', - 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: '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() { - console.log("soft reset"); - // 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)); - // } - } - setTsconfigInUse(tsconfigFilePath) { - 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) { - // 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) { - 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); - } - } - 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); - } - toggleIfThisIsntSelected(btn) { - if (btn.hasClass('selected')) { - this.expanded = !this.expanded; - } - } - selectPanel(btn, body, activeList) { - var buttons = [this.buildPanelBtn, this.referencesPanelBtn]; - var bodies = [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; - } - setActivePanel() { - if (this.buildPanelBtn.hasClass('selected')) { - this.buildPanelSelected(); - } - if (this.referencesPanelBtn.hasClass('selected')) { - this.referencesPanelSelected(); - } - } - toggle() { - this.expanded = !this.expanded; - this.setActivePanel(); - } - ////////////// REFERENCES - setReferences(references) { - // 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 }); - } - } - ///////////////////// BUILD - setBuildPanelCount(errorCount, 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) { - this.buildBody.append(view.$); - } - setBuildProgress(progress) { - // 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 }); - }); - } - } -} -exports.MainPanelView = MainPanelView; -function attach() { - const view = new MainPanelView({}); - atom.workspace.addBottomPanel({ item: view, priority: 1000, visible: true }); - return { - show() { view.$.show(); }, - hide() { view.$.hide(); }, - view - }; -} -exports.attach = attach; diff --git a/dist/main/atom/views/projectSymbolsView.js b/dist/main/atom/views/projectSymbolsView.js deleted file mode 100644 index d2c82c4eb..000000000 --- a/dist/main/atom/views/projectSymbolsView.js +++ /dev/null @@ -1,60 +0,0 @@ -"use strict"; -const sp = require("atom-space-pen-views"); -const atomUtils = require("../atomUtils"); -/** - * https://github.com/atom/atom-space-pen-views - */ -class ProjectSymbolsView extends sp.SelectListView { - constructor() { - super(...arguments); - this.panel = null; - } - get $() { - return this; - } - get filterView() { - return { - $: this.filterEditorView, - model: this.filterEditorView.model - }; - } - setNavBarItems(tsItems) { - super.setMaxItems(40); - var items = tsItems; - super.setItems(items); - } - /** override */ - viewForItem(item) { - return ` -
  • -
    ${item.name}
    -
    ${item.kind}
    -
    ${item.fileName} : ${item.position.line + 1}
    -
  • - `; - } - /** override */ - confirmed(item) { - atom.workspace.open(item.filePath, { - initialLine: item.position.line, - initialColumn: item.position.col - }); - this.hide(); - } - getFilterKey() { return 'name'; } - 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(); - } -} -exports.ProjectSymbolsView = ProjectSymbolsView; diff --git a/dist/main/atomts.js b/dist/main/atomts.js index 25c48a7a7..a48ab884d 100644 --- a/dist/main/atomts.js +++ b/dist/main/atomts.js @@ -2,7 +2,7 @@ const tslib_1 = require("tslib"); // import {getFileStatus} from "./atom/fileStatusCache" // import {$} from "atom-space-pen-views" -// import * as atomUtils from './atom/atomUtils' +// import * as atomUtils from './atom/utils' // import * as fs from 'fs' // import * as path from 'path' const Atom = require("atom"); diff --git a/dist/main/errorPusher.js b/dist/main/errorPusher.js index 7906ff0df..d5c40bd20 100644 --- a/dist/main/errorPusher.js +++ b/dist/main/errorPusher.js @@ -1,6 +1,6 @@ "use strict"; const lodash_1 = require("lodash"); -const atomUtils_1 = require("./atom/atomUtils"); +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() { @@ -14,7 +14,7 @@ class ErrorPusher { type: "Error", text: diagnostic.text, filePath: filePath, - range: diagnostic.start ? atomUtils_1.locationsToRange(diagnostic.start, diagnostic.end) : undefined + range: diagnostic.start ? utils_1.locationsToRange(diagnostic.start, diagnostic.end) : undefined }); } } diff --git a/dist/main/typescriptBuffer.js b/dist/main/typescriptBuffer.js index d3a1d22ce..bb622cd06 100644 --- a/dist/main/typescriptBuffer.js +++ b/dist/main/typescriptBuffer.js @@ -4,7 +4,7 @@ const tslib_1 = require("tslib"); // the editor panes, but is also useful for editor-less buffer changes (renameRefactor). const atom_1 = require("atom"); const events_1 = require("events"); -const atomUtils_1 = require("./atom/atomUtils"); +const utils_1 = require("./atom/utils"); class TypescriptBuffer { constructor(buffer, getClient) { this.buffer = buffer; @@ -57,7 +57,7 @@ class TypescriptBuffer { open() { return tslib_1.__awaiter(this, void 0, void 0, function* () { const filePath = this.buffer.getPath(); - if (atomUtils_1.isTypescriptFile(filePath)) { + 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); diff --git a/dist/main/typescriptEditorPane.js b/dist/main/typescriptEditorPane.js index 133fee1e3..5efc20d20 100644 --- a/dist/main/typescriptEditorPane.js +++ b/dist/main/typescriptEditorPane.js @@ -4,7 +4,7 @@ const atom_space_pen_views_1 = require("atom-space-pen-views"); const path_1 = require("path"); const atom_1 = require("atom"); const lodash_1 = require("lodash"); -const atomUtils_1 = require("./atom/atomUtils"); +const utils_1 = require("./atom/utils"); const typescriptBuffer_1 = require("./typescriptBuffer"); const tooltipManager = require("./atom/tooltipManager"); class TypescriptEditorPane { @@ -54,7 +54,7 @@ class TypescriptEditorPane { }).then(result => { this.clearOccurrenceMarkers(); for (const ref of result.body) { - const marker = this.editor.markBufferRange(atomUtils_1.spanToRange(ref)); + const marker = this.editor.markBufferRange(utils_1.spanToRange(ref)); this.editor.decorateMarker(marker, { type: "highlight", class: "atom-typescript-occurrence" diff --git a/dist/main/utils/fsUtil.js b/dist/main/utils/fsUtil.js index f691f5e28..e69de29bb 100644 --- a/dist/main/utils/fsUtil.js +++ b/dist/main/utils/fsUtil.js @@ -1,33 +0,0 @@ -/** - * Wraps fs and path into a nice "consistentPath" API - */ -"use strict"; -/** we work with "/" for all paths (so does the typescript language service) */ -function consistentPath(filePath) { - return filePath.split('\\').join('/'); -} -exports.consistentPath = consistentPath; -const path = require("path"); -/** - * 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; diff --git a/dist/main/utils/tsUtil.js b/dist/main/utils/tsUtil.js deleted file mode 100644 index e69de29bb..000000000 diff --git a/lib/main/atom/autoCompleteProvider.ts b/lib/main/atom/autoCompleteProvider.ts index a15ab5eff..1c3d861fe 100644 --- a/lib/main/atom/autoCompleteProvider.ts +++ b/lib/main/atom/autoCompleteProvider.ts @@ -1,6 +1,6 @@ // more: https://github.com/atom-community/autocomplete-plus/wiki/Provider-API import {ClientResolver} from "../../client/clientResolver" -import {kindToType, FileLocationQuery} from "./atomUtils" +import {kindToType, FileLocationQuery} from "./utils" import {Provider, RequestOptions, Suggestion} from "../../typings/autocomplete" import {TypescriptServiceClient} from "../../client/client" import * as fuzzaldrin from "fuzzaldrin" diff --git a/lib/main/atom/commands/build.ts b/lib/main/atom/commands/build.ts index b15f51e01..c812a5cbd 100644 --- a/lib/main/atom/commands/build.ts +++ b/lib/main/atom/commands/build.ts @@ -1,5 +1,5 @@ import {commands} from "./registry" -import {commandForTypeScript, getFilePathPosition} from "../atomUtils" +import {commandForTypeScript, getFilePathPosition} from "../utils" commands.set("typescript:build", deps => { return async e => { diff --git a/lib/main/atom/commands/checkAllFiles.ts b/lib/main/atom/commands/checkAllFiles.ts index 7e884e2bc..5e9801675 100644 --- a/lib/main/atom/commands/checkAllFiles.ts +++ b/lib/main/atom/commands/checkAllFiles.ts @@ -1,5 +1,5 @@ import {commands} from "./registry" -import {commandForTypeScript, getFilePathPosition} from "../atomUtils" +import {commandForTypeScript, getFilePathPosition} from "../utils" commands.set("typescript:check-all-files", deps => { return async e => { diff --git a/lib/main/atom/commands/findReferences.ts b/lib/main/atom/commands/findReferences.ts index 036ad6c35..fa4c42d04 100644 --- a/lib/main/atom/commands/findReferences.ts +++ b/lib/main/atom/commands/findReferences.ts @@ -1,5 +1,5 @@ import {commands} from "./registry" -import {commandForTypeScript, getFilePathPosition} from "../atomUtils" +import {commandForTypeScript, getFilePathPosition} from "../utils" import {simpleSelectionView} from "../views/simpleSelectionView" import escapeHtml = require('escape-html') diff --git a/lib/main/atom/commands/formatCode.ts b/lib/main/atom/commands/formatCode.ts index 332b30e61..28f0fb2d3 100644 --- a/lib/main/atom/commands/formatCode.ts +++ b/lib/main/atom/commands/formatCode.ts @@ -5,7 +5,7 @@ import { rangeToLocationRange, formatCode, CodeEdit -} from "../atomUtils" +} from "../utils" commands.set("typescript:format-code", deps => { return async e => { diff --git a/lib/main/atom/commands/goToDeclaration.ts b/lib/main/atom/commands/goToDeclaration.ts index 909e66553..7bd8cca9c 100644 --- a/lib/main/atom/commands/goToDeclaration.ts +++ b/lib/main/atom/commands/goToDeclaration.ts @@ -1,5 +1,5 @@ import {commands} from "./registry" -import {commandForTypeScript, getFilePathPosition} from "../atomUtils" +import {commandForTypeScript, getFilePathPosition} from "../utils" import {simpleSelectionView} from "../views/simpleSelectionView" commands.set("typescript:go-to-declaration", deps => { diff --git a/lib/main/atom/commands/index.ts b/lib/main/atom/commands/index.ts index 6c9ac4293..39e924c0b 100644 --- a/lib/main/atom/commands/index.ts +++ b/lib/main/atom/commands/index.ts @@ -1,4 +1,4 @@ -// import atomUtils = require("../atomUtils"); +// import atomUtils = require("../utils"); // import path = require('path'); // import renameView = require("../views/renameView"); // import fileSymbolsView = require("../views/fileSymbolsView"); diff --git a/lib/main/atom/commands/renameRefactor.ts b/lib/main/atom/commands/renameRefactor.ts index a09b0992f..29e3af07b 100644 --- a/lib/main/atom/commands/renameRefactor.ts +++ b/lib/main/atom/commands/renameRefactor.ts @@ -1,6 +1,6 @@ import {commands} from "./registry" -import {commandForTypeScript, getFilePathPosition} from "../atomUtils" -import {spanToRange} from "../atomUtils" +import {commandForTypeScript, getFilePathPosition} from "../utils" +import {spanToRange} from "../utils" commands.set("typescript:rename-refactor", deps => { return async e => { diff --git a/lib/main/atom/components/statusPanel.tsx b/lib/main/atom/components/statusPanel.tsx index 88037f5f0..fd4824cf3 100644 --- a/lib/main/atom/components/statusPanel.tsx +++ b/lib/main/atom/components/statusPanel.tsx @@ -3,7 +3,7 @@ import {dirname} from "path" import { getFilePathRelativeToAtomProject, openFile, -} from "../atomUtils" +} from "../utils" export class StatusPanel extends HTMLElement { diff --git a/lib/main/atom/fileStatusCache.ts b/lib/main/atom/fileStatusCache.ts deleted file mode 100644 index 5faf62344..000000000 --- a/lib/main/atom/fileStatusCache.ts +++ /dev/null @@ -1,21 +0,0 @@ -/** - * We keep an in memory cache of certain knowledge points regarding a few file paths - * This file maintains that - */ -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/tooltipManager.ts b/lib/main/atom/tooltipManager.ts index 1f92ac798..bf83b292b 100644 --- a/lib/main/atom/tooltipManager.ts +++ b/lib/main/atom/tooltipManager.ts @@ -1,7 +1,7 @@ // Inspiration : https://atom.io/packages/ide-haskell // and https://atom.io/packages/ide-flow -import atomUtils = require('./atomUtils'); ///ts:import:generated +import atomUtils = require('./utils'); ///ts:import:generated import {clientResolver} from "../atomts" import path = require('path'); diff --git a/lib/main/atom/atomUtils.ts b/lib/main/atom/utils/atom.ts similarity index 87% rename from lib/main/atom/atomUtils.ts rename to lib/main/atom/utils/atom.ts index e8eac9c31..89e88720f 100644 --- a/lib/main/atom/atomUtils.ts +++ b/lib/main/atom/utils/atom.ts @@ -1,47 +1,14 @@ import * as Atom from "atom" import * as fs from "fs" -import * as fsu from "../utils/fsUtil" import * as path from "path" import * as url from "url" -import {TextSpan, CodeEdit} from "typescript/lib/protocol" -import {Point, Range} from "atom" - -export {TextSpan, CodeEdit} - -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, end): 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 - } -} +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 { @@ -123,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); @@ -156,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) { @@ -235,7 +202,7 @@ export function commandForTypeScript(e: AtomCore.CommandEvent) { /** 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 = { @@ -318,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); diff --git a/lib/main/atom/utils/fs.ts b/lib/main/atom/utils/fs.ts new file mode 100644 index 000000000..b164ff4b2 --- /dev/null +++ b/lib/main/atom/utils/fs.ts @@ -0,0 +1,33 @@ +/** + * 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('/'); +} + +import * as path from "path"; + +/** + * Resolves to to an absolute path. + * @param from,to,to,to... + */ +export function resolve(...args: string[]) { + return consistentPath(path.resolve(...args)); +} + +/** + * 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('.')); +} 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..000ab9e70 --- /dev/null +++ b/lib/main/atom/utils/ts.ts @@ -0,0 +1,39 @@ +import {TextSpan, CodeEdit} from "typescript/lib/protocol" +import {Point, Range} from "atom" + +export {TextSpan, CodeEdit} + +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, end): 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/atomts.ts b/lib/main/atomts.ts index 2ded36add..f297b6167 100644 --- a/lib/main/atomts.ts +++ b/lib/main/atomts.ts @@ -1,6 +1,6 @@ // import {getFileStatus} from "./atom/fileStatusCache" // import {$} from "atom-space-pen-views" -// import * as atomUtils from './atom/atomUtils' +// import * as atomUtils from './atom/utils' // import * as fs from 'fs' // import * as path from 'path' import * as Atom from "atom" diff --git a/lib/main/errorPusher.ts b/lib/main/errorPusher.ts index 83b474aef..b6c674b0f 100644 --- a/lib/main/errorPusher.ts +++ b/lib/main/errorPusher.ts @@ -1,7 +1,7 @@ import {debounce} from "lodash" import {Diagnostic} from "typescript/lib/protocol" import {Linter, LinterMessage} from "../typings/linter" -import {locationsToRange} from "./atom/atomUtils" +import {locationsToRange} from "./atom/utils" /** Class that collects errors from all of the clients and pushes them to the Linter service */ export class ErrorPusher { diff --git a/lib/main/typescriptBuffer.ts b/lib/main/typescriptBuffer.ts index fbcfb7900..6b3b90c2a 100644 --- a/lib/main/typescriptBuffer.ts +++ b/lib/main/typescriptBuffer.ts @@ -3,7 +3,7 @@ import {CompositeDisposable} from "atom" import {TypescriptServiceClient as Client} from "../client/client" import {EventEmitter} from "events" -import {isTypescriptFile} from "./atom/atomUtils" +import {isTypescriptFile} from "./atom/utils" export class TypescriptBuffer { // Timestamps for buffer events diff --git a/lib/main/typescriptEditorPane.ts b/lib/main/typescriptEditorPane.ts index 673e3825a..1990a0448 100644 --- a/lib/main/typescriptEditorPane.ts +++ b/lib/main/typescriptEditorPane.ts @@ -2,7 +2,7 @@ import {$} from "atom-space-pen-views" import {basename} from "path" import {CompositeDisposable} from "atom" import {debounce, flatten} from "lodash" -import {spanToRange} from "./atom/atomUtils" +import {spanToRange} from "./atom/utils" import {TypescriptServiceClient} from "../client/client" import {TypescriptBuffer} from "./typescriptBuffer" import {StatusPanel} from "./atom/components/statusPanel" diff --git a/lib/main/utils/fsUtil.ts b/lib/main/utils/fsUtil.ts index b164ff4b2..e69de29bb 100644 --- a/lib/main/utils/fsUtil.ts +++ b/lib/main/utils/fsUtil.ts @@ -1,33 +0,0 @@ -/** - * 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('/'); -} - -import * as path from "path"; - -/** - * Resolves to to an absolute path. - * @param from,to,to,to... - */ -export function resolve(...args: string[]) { - return consistentPath(path.resolve(...args)); -} - -/** - * 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('.')); -} From 3271f053b5c7e4bc9659cbe27672631dbf00feaf Mon Sep 17 00:00:00 2001 From: Guntars Asmanis-Graham Date: Sun, 8 Jan 2017 17:36:48 -0500 Subject: [PATCH 51/70] Use default tab width for format cmd --- dist/client/client.js | 4 ++++ dist/main/atom/commands/formatCode.js | 27 ++++++--------------- dist/main/atomts.js | 7 ------ lib/client/client.ts | 4 ++++ lib/main/atom/commands/formatCode.ts | 34 +++++++++------------------ lib/main/atom/utils/ts.ts | 4 ++-- lib/main/atomts.ts | 17 ++++---------- 7 files changed, 32 insertions(+), 65 deletions(-) diff --git a/dist/client/client.js b/dist/client/client.js index 4a4e8be25..baa813549 100644 --- a/dist/client/client.js +++ b/dist/client/client.js @@ -9,6 +9,7 @@ exports.CommandWithResponse = new Set([ "compileOnSaveEmitFile", "completionEntryDetails", "completions", + "configure", "definition", "format", "occurrences", @@ -66,6 +67,9 @@ class TypescriptServiceClient { executeCompletionDetails(args) { return this.execute("completionEntryDetails", args); } + executeConfigure(args) { + return this.execute("configure", args); + } executeDefinition(args) { return this.execute("definition", args); } diff --git a/dist/main/atom/commands/formatCode.js b/dist/main/atom/commands/formatCode.js index 68ad4713e..0fe1e04c1 100644 --- a/dist/main/atom/commands/formatCode.js +++ b/dist/main/atom/commands/formatCode.js @@ -27,9 +27,14 @@ registry_1.commands.set("typescript:format-code", deps => { } const client = yield deps.getClient(filePath); const edits = []; - // Collect all edits together so we can update in a single transaction + // TODO: Read these from package settings and/or tsconfig.json + const options = { + indentSize: atom.config.get("editor.tabLength"), + tabSize: atom.config.get("editor.tabLength"), + }; + // Collect all edits together so we can update everything in a single transaction for (const range of ranges) { - const result = yield client.executeFormat(tslib_1.__assign({}, range, { file: filePath })); + const result = yield client.executeFormat(tslib_1.__assign({}, range, { options, file: filePath })); if (result.body) { edits.push(...result.body); } @@ -39,23 +44,5 @@ registry_1.commands.set("typescript:format-code", deps => { utils_1.formatCode(editor, edits); }); } - // if (selection.isEmpty()) { - // console.log("no selection, format all") - // parent.formatDocument({ filePath: filePath }).then((result) => { - // if (!result.edits.length) return; - // editor.transact(() => { - // atomUtils.formatCode(editor, result.edits); - // }); - // }); - // } else { - // console.log("selcetion", selection, filePath) - // - // 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); - // }); - // }); - // } }); }); diff --git a/dist/main/atomts.js b/dist/main/atomts.js index a48ab884d..f6930a5c6 100644 --- a/dist/main/atomts.js +++ b/dist/main/atomts.js @@ -1,10 +1,5 @@ "use strict"; const tslib_1 = require("tslib"); -// import {getFileStatus} from "./atom/fileStatusCache" -// import {$} from "atom-space-pen-views" -// import * as atomUtils from './atom/utils' -// import * as fs from 'fs' -// import * as path from 'path' const Atom = require("atom"); const atomConfig = require("./atom/atomConfig"); const hyperclickProvider = require("../hyperclickProvider"); @@ -151,11 +146,9 @@ function serialize() { } exports.serialize = serialize; function consumeLinter(registry) { - console.log("consume linter"); linter = registry.register({ name: "" }); - console.log("linter is", linter); } exports.consumeLinter = consumeLinter; function consumeStatusBar(_statusBar) { diff --git a/lib/client/client.ts b/lib/client/client.ts index 8fb7eb938..9258e249a 100644 --- a/lib/client/client.ts +++ b/lib/client/client.ts @@ -9,6 +9,7 @@ export const CommandWithResponse = new Set([ "compileOnSaveEmitFile", "completionEntryDetails", "completions", + "configure", "definition", "format", "occurrences", @@ -68,6 +69,9 @@ export class TypescriptServiceClient { 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) } diff --git a/lib/main/atom/commands/formatCode.ts b/lib/main/atom/commands/formatCode.ts index 28f0fb2d3..bad5861fb 100644 --- a/lib/main/atom/commands/formatCode.ts +++ b/lib/main/atom/commands/formatCode.ts @@ -1,10 +1,11 @@ import {commands} from "./registry" import { + CodeEdit, commandForTypeScript, + formatCode, + FormatCodeSettings, LocationRangeQuery, rangeToLocationRange, - formatCode, - CodeEdit } from "../utils" commands.set("typescript:format-code", deps => { @@ -37,9 +38,15 @@ commands.set("typescript:format-code", deps => { const client = await deps.getClient(filePath) const edits: CodeEdit[] = [] - // Collect all edits together so we can update in a single transaction + // TODO: Read these from package settings and/or tsconfig.json + const options: FormatCodeSettings = { + indentSize: atom.config.get("editor.tabLength"), + tabSize: atom.config.get("editor.tabLength"), + } + + // Collect all edits together so we can update everything in a single transaction for (const range of ranges) { - const result = await client.executeFormat({...range, file: filePath}) + const result = await client.executeFormat({...range, options, file: filePath}) if (result.body) { edits.push(...result.body) } @@ -50,24 +57,5 @@ commands.set("typescript:format-code", deps => { formatCode(editor, edits) }) } - - // if (selection.isEmpty()) { - // console.log("no selection, format all") - // parent.formatDocument({ filePath: filePath }).then((result) => { - // if (!result.edits.length) return; - // editor.transact(() => { - // atomUtils.formatCode(editor, result.edits); - // }); - // }); - // } else { - // console.log("selcetion", selection, filePath) - // - // 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); - // }); - // }); - // } } }) diff --git a/lib/main/atom/utils/ts.ts b/lib/main/atom/utils/ts.ts index 000ab9e70..8ab03dff3 100644 --- a/lib/main/atom/utils/ts.ts +++ b/lib/main/atom/utils/ts.ts @@ -1,7 +1,7 @@ -import {TextSpan, CodeEdit} from "typescript/lib/protocol" +import {TextSpan, CodeEdit, FormatCodeSettings} from "typescript/lib/protocol" import {Point, Range} from "atom" -export {TextSpan, CodeEdit} +export {TextSpan, CodeEdit, FormatCodeSettings} export interface LocationQuery { line: number diff --git a/lib/main/atomts.ts b/lib/main/atomts.ts index f297b6167..5d0a3ab7b 100644 --- a/lib/main/atomts.ts +++ b/lib/main/atomts.ts @@ -1,8 +1,3 @@ -// import {getFileStatus} from "./atom/fileStatusCache" -// import {$} from "atom-space-pen-views" -// import * as atomUtils from './atom/utils' -// import * as fs from 'fs' -// import * as path from 'path' import * as Atom from "atom" import * as atomConfig from './atom/atomConfig' import * as hyperclickProvider from "../hyperclickProvider" @@ -174,17 +169,13 @@ export function deactivate() { } export function serialize(): PackageState { - return {}; + return {} } export function consumeLinter(registry: LinterRegistry) { - console.log("consume linter") - - linter = registry.register({ - name: "" - }) - - console.log("linter is", linter) + linter = registry.register({ + name: "" + }) } export function consumeStatusBar(_statusBar) { From c7e03a7d7d3e8041e213378a36b63678a0c3844c Mon Sep 17 00:00:00 2001 From: Guntars Asmanis-Graham Date: Sun, 8 Jan 2017 18:44:44 -0500 Subject: [PATCH 52/70] renameRefactor should use TypescriptBuffer --- dist/main/atom/commands/renameRefactor.js | 12 ++++++------ dist/main/atomts.js | 7 ++++--- dist/main/typescriptBuffer.js | 3 +-- dist/main/typescriptEditorPane.js | 16 ++-------------- lib/main/atom/commands/registry.ts | 3 ++- lib/main/atom/commands/renameRefactor.ts | 14 ++++++++------ lib/main/atomts.ts | 7 ++++--- lib/main/typescriptBuffer.ts | 4 +--- lib/main/typescriptEditorPane.ts | 23 ++++------------------- 9 files changed, 32 insertions(+), 57 deletions(-) diff --git a/dist/main/atom/commands/renameRefactor.js b/dist/main/atom/commands/renameRefactor.js index 7f4904281..acec36009 100644 --- a/dist/main/atom/commands/renameRefactor.js +++ b/dist/main/atom/commands/renameRefactor.js @@ -30,16 +30,16 @@ registry_1.commands.set("typescript:rename-refactor", deps => { } }); locs.map((loc) => tslib_1.__awaiter(this, void 0, void 0, function* () { - const { buffer, isOpen } = yield deps.getBuffer(loc.file); - buffer.transact(() => { + const { buffer, isOpen } = yield deps.getTypescriptBuffer(loc.file); + buffer.buffer.transact(() => { for (const span of loc.locs) { - buffer.setTextInRange(utils_2.spanToRange(span), newName); + buffer.buffer.setTextInRange(utils_2.spanToRange(span), newName); } }); if (!isOpen) { - buffer.save(); - buffer.onDidSave(() => { - buffer.destroy(); + buffer.buffer.save(); + buffer.on("saved", () => { + buffer.buffer.destroy(); }); } })); diff --git a/dist/main/atomts.js b/dist/main/atomts.js index f6930a5c6..bb92d3690 100644 --- a/dist/main/atomts.js +++ b/dist/main/atomts.js @@ -13,6 +13,7 @@ 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(); @@ -54,12 +55,12 @@ function activate(state) { clearErrors() { errorPusher.clear(); }, - getBuffer(filePath) { + 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.editor.buffer, + buffer: pane.buffer, isOpen: true }; } @@ -74,7 +75,7 @@ function activate(state) { }); }); return { - buffer, + buffer: new typescriptBuffer_1.TypescriptBuffer(buffer, filePath => exports.clientResolver.get(filePath)), isOpen: false }; }); diff --git a/dist/main/typescriptBuffer.js b/dist/main/typescriptBuffer.js index bb622cd06..19eb23d26 100644 --- a/dist/main/typescriptBuffer.js +++ b/dist/main/typescriptBuffer.js @@ -12,7 +12,6 @@ class TypescriptBuffer { this.events = new events_1.EventEmitter(); this.subscriptions = new atom_1.CompositeDisposable(); this.dispose = () => { - console.warn("buffer disposed"); this.subscriptions.dispose(); if (this.isOpen) { this.clientPromise.then(client => client.executeClose({ file: this.buffer.getPath() })); @@ -34,7 +33,6 @@ class TypescriptBuffer { if (changes.length === 0 || !this.isOpen) { return; } - console.warn("onDidStopChanging", this, changes); this.changedAtBatch = Date.now(); const client = yield this.clientPromise; const filePath = this.buffer.getPath(); @@ -49,6 +47,7 @@ class TypescriptBuffer { 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)); diff --git a/dist/main/typescriptEditorPane.js b/dist/main/typescriptEditorPane.js index 5efc20d20..f8b0b3671 100644 --- a/dist/main/typescriptEditorPane.js +++ b/dist/main/typescriptEditorPane.js @@ -1,7 +1,6 @@ "use strict"; const tslib_1 = require("tslib"); const atom_space_pen_views_1 = require("atom-space-pen-views"); -const path_1 = require("path"); const atom_1 = require("atom"); const lodash_1 = require("lodash"); const utils_1 = require("./atom/utils"); @@ -12,7 +11,6 @@ class TypescriptEditorPane { // Path to the project's tsconfig.json this.configFile = ""; this.isActive = false; - this.isTSConfig = false; this.isTypescript = false; this.isOpen = false; this.occurrenceMarkers = []; @@ -22,8 +20,8 @@ class TypescriptEditorPane { 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) { - // The first activation might happen before we even have a client this.client.executeGetErr({ files: [this.filePath], delay: 100 @@ -34,7 +32,6 @@ class TypescriptEditorPane { this.opts.statusPanel.setTsConfigPath(this.configFile); }; this.onChanged = () => { - console.warn("changed event"); this.opts.statusPanel.setBuildStatus(undefined); this.client.executeGetErr({ files: [this.filePath], @@ -77,7 +74,6 @@ class TypescriptEditorPane { this.dispose(); }; this.onOpened = () => tslib_1.__awaiter(this, void 0, void 0, function* () { - console.warn("opened event"); this.client = yield this.opts.getClient(this.filePath); this.subscriptions.add(this.editor.onDidChangeCursorPosition(this.onDidChangeCursorPosition)); this.subscriptions.add(this.editor.onDidDestroy(this.onDidDestroy)); @@ -102,16 +98,11 @@ class TypescriptEditorPane { } }); this.onSaved = () => { - console.warn("saved event"); + this.filePath = this.editor.getPath(); if (this.opts.onSave) { this.opts.onSave(this); } this.compileOnSave(); - // if (this.filePath !== event.path) { - // this.client = await this.opts.getClient(event.path) - // this.filePath = event.path - // this.isTSConfig = basename(this.filePath) === "tsconfig.json" - // } }; this.editor = editor; this.filePath = editor.getPath(); @@ -124,9 +115,6 @@ class TypescriptEditorPane { this.subscriptions.add(editor.onDidChangeGrammar(grammar => { this.isTypescript = isTypescriptGrammar(grammar); })); - if (this.filePath) { - this.isTSConfig = path_1.basename(this.filePath) === "tsconfig.json"; - } this.setupTooltipView(); } dispose() { diff --git a/lib/main/atom/commands/registry.ts b/lib/main/atom/commands/registry.ts index 36e693784..ee9771fb4 100644 --- a/lib/main/atom/commands/registry.ts +++ b/lib/main/atom/commands/registry.ts @@ -1,10 +1,11 @@ import {TypescriptServiceClient} from "../../../client/client" import {RenameView} from "../views/renameView" import {StatusPanel} from "../../atom/components/statusPanel" +import {TypescriptBuffer} from "../../typescriptBuffer" export interface Dependencies { clearErrors() - getBuffer(filePath: string): Promise<{buffer: TextBuffer.ITextBuffer, isOpen: boolean}> + getTypescriptBuffer(filePath: string): Promise<{buffer: TypescriptBuffer, isOpen: boolean}> getClient(filePath: string): Promise renameView: RenameView statusPanel: StatusPanel diff --git a/lib/main/atom/commands/renameRefactor.ts b/lib/main/atom/commands/renameRefactor.ts index 29e3af07b..fb6717454 100644 --- a/lib/main/atom/commands/renameRefactor.ts +++ b/lib/main/atom/commands/renameRefactor.ts @@ -33,16 +33,18 @@ commands.set("typescript:rename-refactor", deps => { }) locs.map(async loc => { - const {buffer, isOpen} = await deps.getBuffer(loc.file) - buffer.transact(() => { + const {buffer, isOpen} = await deps.getTypescriptBuffer(loc.file) + + buffer.buffer.transact(() => { for (const span of loc.locs) { - buffer.setTextInRange(spanToRange(span), newName) + buffer.buffer.setTextInRange(spanToRange(span), newName) } }) + if (!isOpen) { - buffer.save() - buffer.onDidSave(() => { - buffer.destroy() + buffer.buffer.save() + buffer.on("saved", () => { + buffer.buffer.destroy() }) } }) diff --git a/lib/main/atomts.ts b/lib/main/atomts.ts index 5d0a3ab7b..0227fd85b 100644 --- a/lib/main/atomts.ts +++ b/lib/main/atomts.ts @@ -13,6 +13,7 @@ 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 const subscriptions = new CompositeDisposable() @@ -69,11 +70,11 @@ export function activate(state: PackageState) { clearErrors() { errorPusher.clear() }, - async getBuffer(filePath: string) { + async getTypescriptBuffer(filePath: string) { const pane = panes.find(pane => pane.filePath === filePath) if (pane) { return { - buffer: pane.editor.buffer, + buffer: pane.buffer, isOpen: true } } @@ -91,7 +92,7 @@ export function activate(state: PackageState) { }) return { - buffer, + buffer: new TypescriptBuffer(buffer, filePath => clientResolver.get(filePath)), isOpen: false } }, diff --git a/lib/main/typescriptBuffer.ts b/lib/main/typescriptBuffer.ts index 6b3b90c2a..95b990d45 100644 --- a/lib/main/typescriptBuffer.ts +++ b/lib/main/typescriptBuffer.ts @@ -24,6 +24,7 @@ export class TypescriptBuffer { 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)) @@ -53,7 +54,6 @@ export class TypescriptBuffer { } dispose = () => { - console.warn("buffer disposed") this.subscriptions.dispose() if (this.isOpen) { @@ -90,8 +90,6 @@ export class TypescriptBuffer { return } - console.warn("onDidStopChanging", this, changes) - this.changedAtBatch = Date.now() const client = await this.clientPromise diff --git a/lib/main/typescriptEditorPane.ts b/lib/main/typescriptEditorPane.ts index 1990a0448..54f130563 100644 --- a/lib/main/typescriptEditorPane.ts +++ b/lib/main/typescriptEditorPane.ts @@ -1,5 +1,4 @@ import {$} from "atom-space-pen-views" -import {basename} from "path" import {CompositeDisposable} from "atom" import {debounce, flatten} from "lodash" import {spanToRange} from "./atom/utils" @@ -27,7 +26,6 @@ export class TypescriptEditorPane implements AtomCore.Disposable { filePath: string isActive = false - isTSConfig = false isTypescript = false private opts: PaneOptions @@ -52,10 +50,6 @@ export class TypescriptEditorPane implements AtomCore.Disposable { this.isTypescript = isTypescriptGrammar(grammar) })) - if (this.filePath) { - this.isTSConfig = basename(this.filePath) === "tsconfig.json" - } - this.setupTooltipView() } @@ -71,8 +65,8 @@ export class TypescriptEditorPane implements AtomCore.Disposable { if (this.isTypescript && this.filePath) { this.opts.statusPanel.show() + // The first activation might happen before we even have a client if (this.client) { - // The first activation might happen before we even have a client this.client.executeGetErr({ files: [this.filePath], delay: 100 @@ -86,8 +80,6 @@ export class TypescriptEditorPane implements AtomCore.Disposable { } onChanged = () => { - console.warn("changed event") - this.opts.statusPanel.setBuildStatus(undefined) this.client.executeGetErr({ @@ -146,8 +138,6 @@ export class TypescriptEditorPane implements AtomCore.Disposable { } onOpened = async () => { - console.warn("opened event") - this.client = await this.opts.getClient(this.filePath) this.subscriptions.add(this.editor.onDidChangeCursorPosition(this.onDidChangeCursorPosition)) @@ -178,19 +168,14 @@ export class TypescriptEditorPane implements AtomCore.Disposable { } } - onSaved = () => { - console.warn("saved event") + onSaved = () => { + this.filePath = this.editor.getPath() + if (this.opts.onSave) { this.opts.onSave(this) } this.compileOnSave() - - // if (this.filePath !== event.path) { - // this.client = await this.opts.getClient(event.path) - // this.filePath = event.path - // this.isTSConfig = basename(this.filePath) === "tsconfig.json" - // } } async compileOnSave() { From f281baf51a17068bae215c8426405b3eb8f0c4df Mon Sep 17 00:00:00 2001 From: Guntars Asmanis-Graham Date: Sat, 28 Jan 2017 16:21:44 -0500 Subject: [PATCH 53/70] Update Typescript to the latest nightly --- lib/tsconfig.json | 3 ++- package.json | 3 ++- 2 files changed, 4 insertions(+), 2 deletions(-) diff --git a/lib/tsconfig.json b/lib/tsconfig.json index a48b50232..e6ddaca24 100644 --- a/lib/tsconfig.json +++ b/lib/tsconfig.json @@ -1,15 +1,16 @@ { "compilerOptions": { + "forceConsistentCasingInFileNames": true, "importHelpers": true, "jsx": "react", "lib": ["es6", "dom"], "module": "commonjs", - "forceConsistentCasingInFileNames": true, "noLib": false, "noUnusedLocals": true, "outDir": "../dist", "preserveConstEnums": true, "reactNamespace": "dom", + "skipLibCheck": true, "sourceMap": false, "strictNullChecks": true, "target": "es6" diff --git a/package.json b/package.json index 3e26e5230..0cef8a76f 100644 --- a/package.json +++ b/package.json @@ -52,7 +52,7 @@ "dependencies": { "@types/atom": "0.0.35", "@types/byline": "^4.2.31", - "@types/lodash": "4.14.41", + "@types/lodash": "^4.14.51", "@types/resolve": "0.0.4", "atom-package-deps": "^2.0.3", "atom-space-pen-views": "^2.0.4", @@ -70,6 +70,7 @@ "resolve": "1.1.7", "tsconfig": "^2.2.0", "tslib": "1.2.0", + "typescript": "^2.2.0-dev.20170128", "xtend": "^4.0.0" }, "devDependencies": { From 7ba0dd28e8d8f8522da9881f90d04d0390617cf6 Mon Sep 17 00:00:00 2001 From: Guntars Asmanis-Graham Date: Sat, 28 Jan 2017 16:23:10 -0500 Subject: [PATCH 54/70] Update grammar --- grammars/ts.cson | 363 +++++++++++++++++++++++++++------------------- grammars/tsx.cson | 361 ++++++++++++++++++++++++++------------------- 2 files changed, 427 insertions(+), 297 deletions(-) diff --git a/grammars/ts.cson b/grammars/ts.cson index fffe3c266..9801a4869 100644 --- a/grammars/ts.cson +++ b/grammars/ts.cson @@ -1,6 +1,6 @@ # This file is generated by "scripts/grammar.ts" -# Last generated: Wed, 30 Nov 2016 17:55:07 GMT +# Last generated: Sat, 28 Jan 2017 21:22:25 GMT name: "TypeScript" scopeName: "source.ts" @@ -68,9 +68,6 @@ repository: { include: "#comment" } - { - include: "#literal" - } { include: "#declaration" } @@ -133,6 +130,8 @@ repository: (function\\s*[(<]) | (function\\s+) | ([_$[:alpha:]][_$[:alnum:]]*\\s*=>) | + ([(]\\s*(([)]\\s*:)|([_$[:alpha:]][_$[:alnum:]]*\\s*:)|(\\.\\.\\.) )) | + ([<]\\s*[_$[:alpha:]][_$[:alnum:]]*((\\s+extends\\s*[^=>])|(\\s*[,]))) | ((<([^<>]|\\<[^<>]+\\>)+>\\s*)?\\(([^()]|\\([^()]*\\))*\\)(\\s*:\\s*(.)*)?\\s*=>)) ) | (:\\s*( @@ -154,13 +153,20 @@ repository: end: "(?=$|[;,=}]|(\\s+(of|in)\\s+))" patterns: [ { - include: "#type-annotation" - } - { - include: "#string" + include: "#var-single-variable-type-annotation" } + ] + } + { + name: "meta.var-single-variable.expr.ts" + begin: "([[:upper:]][_$[:digit:][:upper:]]*)(?![_$[:alnum:]])" + beginCaptures: + "1": + name: "meta.definition.variable.ts variable.other.constant.ts" + end: "(?=$|[;,=}]|(\\s+(of|in)\\s+))" + patterns: [ { - include: "#comment" + include: "#var-single-variable-type-annotation" } ] } @@ -173,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: [ { @@ -342,7 +354,6 @@ repository: } ] expression: - name: "meta.expression.ts" patterns: [ { comment: "Match Angular 2 Component html templates" @@ -373,10 +384,7 @@ repository: include: "#comment" } { - include: "#literal" - } - { - include: "#function-declaration" + include: "#function-expression" } { include: "#class-or-interface-declaration" @@ -402,6 +410,9 @@ repository: { include: "#function-call" } + { + include: "#literal" + } { include: "#support-objects" } @@ -432,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*( @@ -1084,7 +1096,7 @@ repository: name: "storage.type.ts" "7": name: "keyword.generator.asterisk.ts" - end: "(?=\\}|;|,)|(?<=\\})" + end: "(?=\\}|;|,|$)|(?<=\\})" patterns: [ { include: "#method-declaration-name" @@ -1101,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*( @@ -1525,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: ''' @@ -1827,6 +1817,10 @@ repository: name: "storage.modifier.ts" match: "(?)" + } { include: "#type" } @@ -1835,22 +1829,40 @@ 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" } { - name: "punctuation.accessor.ts" - match: "\\." + include: "#object-identifiers" + } + { + include: "#punctuation-accessor" } { name: "entity.name.function.ts" @@ -2308,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: "constant.other.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: @@ -2345,7 +2341,7 @@ repository: "1": name: "punctuation.accessor.ts" "2": - name: "constant.other.property.ts" + name: "variable.other.constant.property.ts" } { match: "(\\.)\\s*([_$[:alpha:]][_$[:alnum:]]*)" @@ -2355,31 +2351,53 @@ 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)(?: + (?x)(\\.)\\s*(?: ([[:upper:]][_$[:digit:][:upper:]]*) | ([_$[:alpha:]][_$[:alnum:]]*) )(?=\\s*\\.\\s*[_$[:alpha:]][_$[:alnum:]]*) ''' captures: "1": - name: "constant.other.object.ts" + name: "punctuation.accessor.ts" "2": - name: "variable.other.object.ts" - } - { - name: "constant.other.ts" - match: "([[:upper:]][_$[:digit:][:upper:]]*)(?![_$[:alnum:]])" + name: "variable.other.constant.object.property.ts" + "3": + name: "variable.other.object.property.ts" } { - name: "variable.other.readwrite.ts" - match: "[_$[:alpha:]][_$[:alnum:]]*" + match: ''' + (?x)(?: + ([[:upper:]][_$[:digit:][:upper:]]*) | + ([_$[:alpha:]][_$[:alnum:]]*) + )(?=\\s*\\.\\s*[_$[:alpha:]][_$[:alnum:]]*) + ''' + captures: + "1": + name: "variable.other.constant.object.ts" + "2": + name: "variable.other.object.ts" } ] cast: name: "cast.expr.ts" - begin: "(?:(?<=return|throw|yield|await|default|[=(,:>*]))\\s*(<)(?!*]))\\s*(<)(?!)| + ([(]\\s*(([)]\\s*:)|([_$[:alpha:]][_$[:alnum:]]*\\s*:)|(\\.\\.\\.) )) | + ([<]\\s*[_$[:alpha:]][_$[:alnum:]]*((\\s+extends\\s*[^=>])|(\\s*[,]))) | ((<([^<>]|\\<[^<>]+\\>)+>\\s*)?\\(([^()]|\\([^()]*\\))*\\)(\\s*:\\s*(.)*)?\\s*=>)))) ''' beginCaptures: @@ -2511,6 +2531,14 @@ repository: name: "keyword.control.flow.ts" match: "(?)" @@ -2628,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" @@ -2668,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" } @@ -2740,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": @@ -2758,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,20 @@ repository: end: "(?=$|[;,=}]|(\\s+(of|in)\\s+))" patterns: [ { - include: "#type-annotation" - } - { - include: "#string" + include: "#var-single-variable-type-annotation" } + ] + } + { + name: "meta.var-single-variable.expr.tsx" + begin: "([[:upper:]][_$[:digit:][:upper:]]*)(?![_$[:alnum:]])" + beginCaptures: + "1": + name: "meta.definition.variable.tsx variable.other.constant.tsx" + end: "(?=$|[;,=}]|(\\s+(of|in)\\s+))" + patterns: [ { - include: "#comment" + include: "#var-single-variable-type-annotation" } ] } @@ -173,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: [ { @@ -342,7 +354,6 @@ repository: } ] expression: - name: "meta.expression.tsx" patterns: [ { comment: "Match Angular 2 Component html templates" @@ -376,10 +387,7 @@ repository: include: "#comment" } { - include: "#literal" - } - { - include: "#function-declaration" + include: "#function-expression" } { include: "#class-or-interface-declaration" @@ -405,6 +413,9 @@ repository: { include: "#function-call" } + { + include: "#literal" + } { include: "#support-objects" } @@ -435,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*( @@ -1087,7 +1099,7 @@ repository: name: "storage.type.tsx" "7": name: "keyword.generator.asterisk.tsx" - end: "(?=\\}|;|,)|(?<=\\})" + end: "(?=\\}|;|,|$)|(?<=\\})" patterns: [ { include: "#method-declaration-name" @@ -1104,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*( @@ -1528,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: ''' @@ -1830,6 +1820,10 @@ repository: name: "storage.modifier.tsx" match: "(?)" + } { include: "#type" } @@ -1838,22 +1832,40 @@ 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" } { - name: "punctuation.accessor.tsx" - match: "\\." + include: "#object-identifiers" + } + { + include: "#punctuation-accessor" } { name: "entity.name.function.tsx" @@ -2311,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: "constant.other.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: @@ -2348,7 +2344,7 @@ repository: "1": name: "punctuation.accessor.tsx" "2": - name: "constant.other.property.tsx" + name: "variable.other.constant.property.tsx" } { match: "(\\.)\\s*([_$[:alpha:]][_$[:alnum:]]*)" @@ -2358,26 +2354,48 @@ 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)(?: + (?x)(\\.)\\s*(?: ([[:upper:]][_$[:digit:][:upper:]]*) | ([_$[:alpha:]][_$[:alnum:]]*) )(?=\\s*\\.\\s*[_$[:alpha:]][_$[:alnum:]]*) ''' captures: "1": - name: "constant.other.object.tsx" + name: "punctuation.accessor.tsx" "2": - name: "variable.other.object.tsx" - } - { - name: "constant.other.tsx" - match: "([[:upper:]][_$[:digit:][:upper:]]*)(?![_$[:alnum:]])" + name: "variable.other.constant.object.property.tsx" + "3": + name: "variable.other.object.property.tsx" } { - name: "variable.other.readwrite.tsx" - match: "[_$[:alpha:]][_$[:alnum:]]*" + match: ''' + (?x)(?: + ([[:upper:]][_$[:digit:][:upper:]]*) | + ([_$[:alpha:]][_$[:alnum:]]*) + )(?=\\s*\\.\\s*[_$[:alpha:]][_$[:alnum:]]*) + ''' + captures: + "1": + name: "variable.other.constant.object.tsx" + "2": + name: "variable.other.object.tsx" } ] cast: @@ -2392,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: @@ -2505,6 +2525,14 @@ repository: name: "keyword.control.flow.tsx" match: "(?)" @@ -2622,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" @@ -2662,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" } @@ -2734,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": @@ -2752,7 +2818,7 @@ repository: ] } { - name: "string.regex.tsx" + name: "string.regexp.tsx" begin: "(? Date: Sat, 28 Jan 2017 18:32:04 -0500 Subject: [PATCH 55/70] Make autocomplete less trigger happy and reuse completions --- dist/client/client.js | 12 +-- dist/main/atom/autoCompleteProvider.js | 85 ++++++++++++++------ dist/main/atomts.js | 56 ++++++------- dist/main/typescriptBuffer.js | 26 +++++- lib/client/client.ts | 12 +-- lib/main/atom/autoCompleteProvider.ts | 106 +++++++++++++++++++------ lib/main/atomts.ts | 59 +++++++------- lib/main/typescriptBuffer.ts | 25 +++++- lib/typings/atom_core.d.ts | 1 + 9 files changed, 262 insertions(+), 120 deletions(-) diff --git a/dist/client/client.js b/dist/client/client.js index baa813549..090de06dc 100644 --- a/dist/client/client.js +++ b/dist/client/client.js @@ -30,7 +30,7 @@ class TypescriptServiceClient { if (isResponse(res)) { const callback = this.callbacks[res.request_seq]; if (callback) { - console.log("received response for", res.command, "in", Date.now() - callback.started, "ms", "with data", res.body); + // console.log("received response for", res.command, "in", Date.now() - callback.started, "ms", "with data", res.body) delete this.callbacks[res.request_seq]; if (res.success) { callback.resolve(res); @@ -42,7 +42,7 @@ class TypescriptServiceClient { } } else if (isEvent(res)) { - console.log("received event", res); + // console.log("received event", res) this.events.emit(res.event, res.body); } }; @@ -133,7 +133,7 @@ class TypescriptServiceClient { command, arguments: args }; - console.log("sending request", command, "with args", args); + // console.log("sending request", command, "with args", args) setImmediate(() => { cp.stdin.write(JSON.stringify(req) + "\n"); }); @@ -148,14 +148,14 @@ class TypescriptServiceClient { startServer() { if (!this.serverPromise) { this.serverPromise = new Promise((resolve, reject) => { - console.log("starting", this.tsServerPath); + // console.log("starting", this.tsServerPath) const cp = child_process_1.spawn(this.tsServerPath, this.tsServerArgs); cp.once("error", err => { - console.log("tsserver starting failed with", err); + // console.log("tsserver starting failed with", err) reject(err); }); cp.once("exit", code => { - console.log("tsserver failed to start with code", code); + // console.log("tsserver failed to start with code", code) reject({ code }); }); messageStream(cp.stdout).on("data", this.onMessage); diff --git a/dist/main/atom/autoCompleteProvider.js b/dist/main/atom/autoCompleteProvider.js index 7d8d9c5f6..51f2fdb80 100644 --- a/dist/main/atom/autoCompleteProvider.js +++ b/dist/main/atom/autoCompleteProvider.js @@ -1,32 +1,32 @@ "use strict"; 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) { + constructor(clientResolver, opts) { this.selector = ".source.ts, .source.tsx"; - this.disableForSelector = ".comment.block.documentation.ts, .comment.block.documentation.tsx, .comment.line.double-slash.ts, .comment.line.double-slash.tsx"; + this.disableForSelector = ".comment"; this.inclusionPriority = 3; this.suggestionPriority = 3; this.excludeLowerPriority = false; this.clientResolver = clientResolver; + this.opts = opts; } // Try to reuse the last completions we got from tsserver if they're for the same position. - getSuggestionsWithCache(prefix, location) { + getSuggestionsWithCache(prefix, location, activatedManually) { return tslib_1.__awaiter(this, void 0, void 0, function* () { - // NOTE: While typing this can get out of sync with what tsserver would return so find a better - // way to reuse the completions. - // if (this.lastSuggestions) { - // 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 - // } - // } - // } + 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(tslib_1.__assign({ prefix }, location)); const suggestions = completions.body.map(entry => ({ @@ -47,12 +47,32 @@ class AutocompleteProvider { return tslib_1.__awaiter(this, void 0, void 0, function* () { const location = getLocationQuery(opts); const { prefix } = opts; - console.log("autocomplete", { prefix, location }); 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 []; + } + } + // 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 []; + } + } + // 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); + var suggestions = yield this.getSuggestionsWithCache(prefix, location, opts.activatedManually); } catch (error) { return []; @@ -61,8 +81,8 @@ class AutocompleteProvider { if (alphaPrefix !== "") { suggestions = fuzzaldrin.filter(suggestions, alphaPrefix, { key: "text" }); } - // Get additional details for the first few suggestions, but don't wait for it to complete - this.getAdditionalDetails(suggestions.slice(0, 15), location); + // Get additional details for the first few suggestions + yield this.getAdditionalDetails(suggestions.slice(0, 10), location); const trimmed = prefix.trim(); return suggestions.map(suggestion => (tslib_1.__assign({ replacementPrefix: getReplacementPrefix(prefix, trimmed, suggestion.text) }, suggestion))); }); @@ -98,10 +118,10 @@ function getReplacementPrefix(prefix, trimmed, replacement) { } // 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 getNormalizedCol(prefix, col) { + const length = prefix === "." ? 0 : prefix.length; + return col - length; +} function getLocationQuery(opts) { return { file: opts.editor.getPath(), @@ -109,3 +129,20 @@ function getLocationQuery(opts) { 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; +} diff --git a/dist/main/atomts.js b/dist/main/atomts.js index bb92d3690..2cfb055dd 100644 --- a/dist/main/atomts.js +++ b/dist/main/atomts.js @@ -18,6 +18,7 @@ const typescriptBuffer_1 = require("./typescriptBuffer"); const subscriptions = new atom_1.CompositeDisposable(); exports.clientResolver = new clientResolver_1.ClientResolver(); exports.config = atomConfig.schema; +const panes = []; // Register all custom components require("./atom/components"); const commands_1 = require("./atom/commands"); @@ -55,31 +56,7 @@ function activate(state) { clearErrors() { errorPusher.clear(); }, - 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 - }; - }); - }, + getTypescriptBuffer, getClient(filePath) { return tslib_1.__awaiter(this, void 0, void 0, function* () { const pane = panes.find(pane => pane.filePath === filePath); @@ -93,7 +70,6 @@ function activate(state) { statusPanel, }); let activePane; - const panes = []; const onSave = lodash_1.debounce((pane) => { console.log("checking errors for all panes for", pane.filePath); const files = panes @@ -159,7 +135,7 @@ exports.consumeStatusBar = consumeStatusBar; // Registering an autocomplete provider function provide() { return [ - new autoCompleteProvider_1.AutocompleteProvider(exports.clientResolver), + new autoCompleteProvider_1.AutocompleteProvider(exports.clientResolver, { getTypescriptBuffer }), ]; } exports.provide = provide; @@ -175,3 +151,29 @@ function loadProjectConfig(sourcePath) { }); } 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 + }; + }); +} diff --git a/dist/main/typescriptBuffer.js b/dist/main/typescriptBuffer.js index 19eb23d26..45aae6ea6 100644 --- a/dist/main/typescriptBuffer.js +++ b/dist/main/typescriptBuffer.js @@ -9,6 +9,9 @@ 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 = () => { @@ -22,7 +25,7 @@ class TypescriptBuffer { }; this.onDidSave = () => tslib_1.__awaiter(this, void 0, void 0, function* () { // Check if there isn't a onDidStopChanging event pending. - const { changedAt = 0, changedAtBatch = 0 } = this; + const { changedAt, changedAtBatch } = this; if (changedAt && changedAt > changedAtBatch) { yield new Promise(resolve => this.events.once("changed", resolve)); } @@ -72,6 +75,27 @@ class TypescriptBuffer { } }); } + // 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; diff --git a/lib/client/client.ts b/lib/client/client.ts index 9258e249a..d24435946 100644 --- a/lib/client/client.ts +++ b/lib/client/client.ts @@ -144,7 +144,7 @@ export class TypescriptServiceClient { if (isResponse(res)) { const callback = this.callbacks[res.request_seq] if (callback) { - console.log("received response for", res.command, "in", Date.now() - callback.started, "ms", "with data", res.body) + // console.log("received response for", res.command, "in", Date.now() - callback.started, "ms", "with data", res.body) delete this.callbacks[res.request_seq] if (res.success) { callback.resolve(res) @@ -155,7 +155,7 @@ export class TypescriptServiceClient { this.emitPendingRequests() } } else if (isEvent(res)) { - console.log("received event", res) + // console.log("received event", res) this.events.emit(res.event, res.body) } } @@ -171,7 +171,7 @@ export class TypescriptServiceClient { arguments: args } - console.log("sending request", command, "with args", args) + // console.log("sending request", command, "with args", args) setImmediate(() => { cp.stdin.write(JSON.stringify(req) + "\n") @@ -191,17 +191,17 @@ export class TypescriptServiceClient { startServer() { if (!this.serverPromise) { this.serverPromise = new Promise((resolve, reject) => { - console.log("starting", this.tsServerPath) + // console.log("starting", this.tsServerPath) const cp = spawn(this.tsServerPath, this.tsServerArgs) cp.once("error", err => { - console.log("tsserver starting failed with", err) + // console.log("tsserver starting failed with", err) reject(err) }) cp.once("exit", code => { - console.log("tsserver failed to start with code", code) + // console.log("tsserver failed to start with code", code) reject({code}) }) diff --git a/lib/main/atom/autoCompleteProvider.ts b/lib/main/atom/autoCompleteProvider.ts index 1c3d861fe..02c0658b1 100644 --- a/lib/main/atom/autoCompleteProvider.ts +++ b/lib/main/atom/autoCompleteProvider.ts @@ -2,14 +2,25 @@ 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?} +type Options = { + getTypescriptBuffer: (filePath: string) => Promise<{ + buffer: TypescriptBuffer + isOpen: boolean + }> +} + export class AutocompleteProvider implements Provider { selector = ".source.ts, .source.tsx" - disableForSelector = ".comment.block.documentation.ts, .comment.block.documentation.tsx, .comment.line.double-slash.ts, .comment.line.double-slash.tsx" + + disableForSelector = ".comment" inclusionPriority = 3 suggestionPriority = 3 @@ -30,28 +41,30 @@ export class AutocompleteProvider implements Provider { suggestions: SuggestionWithDetails[] } - constructor(clientResolver: ClientResolver) { + private opts: Options + + constructor(clientResolver: ClientResolver, opts: Options) { this.clientResolver = clientResolver + this.opts = opts } // Try to reuse the last completions we got from tsserver if they're for the same position. async getSuggestionsWithCache( prefix: string, - location: FileLocationQuery + location: FileLocationQuery, + activatedManually: boolean, ): Promise { - // NOTE: While typing this can get out of sync with what tsserver would return so find a better - // way to reuse the completions. - // if (this.lastSuggestions) { - // 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 - // } - // } - // } + 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 = await this.clientResolver.get(location.file) const completions = await client.executeCompletions({prefix, ...location}) @@ -76,14 +89,37 @@ export class AutocompleteProvider implements Provider { const location = getLocationQuery(opts) const {prefix} = opts - console.log("autocomplete", {prefix, location}) - 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 [] + } + } + + // 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 [] + } + } + + // Flush any pending changes for this buffer to get up to date completions + const {buffer} = await this.opts.getTypescriptBuffer(location.file) + await buffer.flush() + try { - var suggestions = await this.getSuggestionsWithCache(prefix, location) + var suggestions = await this.getSuggestionsWithCache(prefix, location, opts.activatedManually) } catch (error) { return [] } @@ -93,8 +129,8 @@ export class AutocompleteProvider implements Provider { suggestions = fuzzaldrin.filter(suggestions, alphaPrefix, {key: "text"}) } - // Get additional details for the first few suggestions, but don't wait for it to complete - this.getAdditionalDetails(suggestions.slice(0, 15), location) + // Get additional details for the first few suggestions + await this.getAdditionalDetails(suggestions.slice(0, 10), location) const trimmed = prefix.trim() @@ -138,10 +174,10 @@ function getReplacementPrefix(prefix: string, trimmed: string, replacement: stri // 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 getNormalizedCol(prefix: string, col: number): number { + const length = prefix === "." ? 0 : prefix.length + return col - length +} function getLocationQuery(opts: RequestOptions): FileLocationQuery { return { @@ -150,3 +186,23 @@ function getLocationQuery(opts: RequestOptions): FileLocationQuery { 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}) => { + 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/atomts.ts b/lib/main/atomts.ts index 0227fd85b..969fbff62 100644 --- a/lib/main/atomts.ts +++ b/lib/main/atomts.ts @@ -19,6 +19,7 @@ import {TypescriptBuffer} from "./typescriptBuffer" const subscriptions = new CompositeDisposable() export const clientResolver = new ClientResolver() export const config = atomConfig.schema +const panes: TypescriptEditorPane[] = [] // Register all custom components import "./atom/components" @@ -70,32 +71,7 @@ export function activate(state: PackageState) { clearErrors() { errorPusher.clear() }, - async 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 - } - }, + getTypescriptBuffer, async getClient(filePath: string) { const pane = panes.find(pane => pane.filePath === filePath) if (pane) { @@ -109,7 +85,6 @@ export function activate(state: PackageState) { }) let activePane: TypescriptEditorPane | undefined - const panes: TypescriptEditorPane[] = [] const onSave = debounce((pane: TypescriptEditorPane) => { console.log("checking errors for all panes for", pane.filePath) @@ -186,7 +161,7 @@ export function consumeStatusBar(_statusBar) { // Registering an autocomplete provider export function provide() { return [ - new AutocompleteProvider(clientResolver), + new AutocompleteProvider(clientResolver, {getTypescriptBuffer}), ] } @@ -201,3 +176,31 @@ export function loadProjectConfig(sourcePath: string): Promise 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/typescriptBuffer.ts b/lib/main/typescriptBuffer.ts index 95b990d45..0dbe972e5 100644 --- a/lib/main/typescriptBuffer.ts +++ b/lib/main/typescriptBuffer.ts @@ -7,8 +7,8 @@ import {isTypescriptFile} from "./atom/utils" export class TypescriptBuffer { // Timestamps for buffer events - changedAt: number - changedAtBatch: number + changedAt: number = 0 + changedAtBatch: number = 0 // Promise that resolves to the correct client for this filePath clientPromise: Promise @@ -53,6 +53,25 @@ export class TypescriptBuffer { } } + // 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() @@ -76,7 +95,7 @@ export class TypescriptBuffer { onDidSave = async () => { // Check if there isn't a onDidStopChanging event pending. - const {changedAt = 0, changedAtBatch = 0} = this + const {changedAt, changedAtBatch} = this if (changedAt && changedAt > changedAtBatch) { await new Promise(resolve => this.events.once("changed", resolve)) } diff --git a/lib/typings/atom_core.d.ts b/lib/typings/atom_core.d.ts index f19b31cd0..b7be45a49 100644 --- a/lib/typings/atom_core.d.ts +++ b/lib/typings/atom_core.d.ts @@ -27,5 +27,6 @@ declare namespace TextBuffer { onDidReload(callback: Function): AtomCore.Disposable onDidDestroy(callback: Function): AtomCore.Disposable onWillThrowWatchError(callback: Function): AtomCore.Disposable + scheduleDidStopChangingEvent() } } From 8d794a08b6e602c452767a47e3e4e144b7826a51 Mon Sep 17 00:00:00 2001 From: Guntars Asmanis-Graham Date: Sat, 28 Jan 2017 18:43:40 -0500 Subject: [PATCH 56/70] Update README and package.json for beta release --- README.md | 4 ++++ package.json | 10 +++++----- 2 files changed, 9 insertions(+), 5 deletions(-) diff --git a/README.md b/README.md index 9b0100f68..f12bc588e 100644 --- a/README.md +++ b/README.md @@ -1,3 +1,7 @@ +# Beta + +This is a fork of the `atom-typescript` package with a very different implementation and, necessarily, different user experience. More info here: https://github.com/TypeStrong/atom-typescript/pull/1166 + # Atom TypeScript [![Join the chat at https://gitter.im/TypeStrong/atom-typescript](https://badges.gitter.im/Join%20Chat.svg)](https://gitter.im/TypeStrong/atom-typescript?utm_source=badge&utm_medium=badge&utm_campaign=pr-badge&utm_content=badge) diff --git a/package.json b/package.json index 0cef8a76f..a009f53e4 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { - "name": "atom-typescript", - "version": "10.1.13", + "name": "atom-typescript-beta", + "version": "11.0.1-beta", "main": "./dist/main/atomts", "preferGlobal": true, "description": "The only TypeScript plugin you will ever need.", @@ -40,14 +40,14 @@ } } }, - "homepage": "http://atom.io/packages/atom-typescript", + "homepage": "https://github.com/TypeStrong/atom-typescript/pull/1166", "repository": { "type": "git", - "url": "https://github.com/TypeStrong/atom-typescript.git" + "url": "https://github.com/guncha/atom-typescript.git" }, "license": "MIT", "bugs": { - "url": "https://github.com/TypeStrong/atom-typescript/issues" + "url": "https://github.com/TypeStrong/atom-typescript/pull/1166" }, "dependencies": { "@types/atom": "0.0.35", From c34b0988e87b47b5a9b6bcc8577d5a086ad66bc8 Mon Sep 17 00:00:00 2001 From: Guntars Asmanis-Graham Date: Sat, 28 Jan 2017 19:00:10 -0500 Subject: [PATCH 57/70] Prepare 11.0.0-beta release --- package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/package.json b/package.json index a009f53e4..4ff49a095 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "atom-typescript-beta", - "version": "11.0.1-beta", + "version": "11.0.0-beta", "main": "./dist/main/atomts", "preferGlobal": true, "description": "The only TypeScript plugin you will ever need.", From 74b6943136e8a7e11954bee1c1ce2f8c904e4d6a Mon Sep 17 00:00:00 2001 From: Guntars Asmanis-Graham Date: Sat, 28 Jan 2017 20:15:41 -0500 Subject: [PATCH 58/70] Make sure the package loads with the new name --- dist/main/atomts.js | 2 +- lib/main/atomts.ts | 2 +- package.json | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/dist/main/atomts.js b/dist/main/atomts.js index 2cfb055dd..aeade4a8e 100644 --- a/dist/main/atomts.js +++ b/dist/main/atomts.js @@ -25,7 +25,7 @@ const commands_1 = require("./atom/commands"); let linter; let statusBar; function activate(state) { - require('atom-package-deps').install('atom-typescript').then(() => { + require('atom-package-deps').install('atom-typescript-beta').then(() => { let statusPriority = 100; for (const panel of statusBar.getRightTiles()) { if (panel.getItem().tagName === "GRAMMAR-SELECTOR-STATUS") { diff --git a/lib/main/atomts.ts b/lib/main/atomts.ts index 969fbff62..091f4e3d1 100644 --- a/lib/main/atomts.ts +++ b/lib/main/atomts.ts @@ -31,7 +31,7 @@ let statusBar: StatusBar interface PackageState {} export function activate(state: PackageState) { - require('atom-package-deps').install('atom-typescript').then(() => { + require('atom-package-deps').install('atom-typescript-beta').then(() => { let statusPriority = 100 for (const panel of statusBar.getRightTiles()) { diff --git a/package.json b/package.json index 4ff49a095..422a3bf4a 100644 --- a/package.json +++ b/package.json @@ -5,7 +5,7 @@ "preferGlobal": true, "description": "The only TypeScript plugin you will ever need.", "activationHooks": [ - "atom-typescript:grammar-used" + "atom-typescript-beta:grammar-used" ], "scripts": { "build": "tsc -p ./lib", From e09bce0f3e1ed24bd0eddf224b97d72e8c00065a Mon Sep 17 00:00:00 2001 From: Guntars Asmanis-Graham Date: Sat, 28 Jan 2017 20:16:10 -0500 Subject: [PATCH 59/70] Use NodeProcess to start tsserver for compat --- dist/client/client.js | 11 +++++++---- lib/client/client.ts | 12 ++++++++---- 2 files changed, 15 insertions(+), 8 deletions(-) diff --git a/dist/client/client.js b/dist/client/client.js index 090de06dc..f0b59db64 100644 --- a/dist/client/client.js +++ b/dist/client/client.js @@ -1,9 +1,9 @@ "use strict"; const tslib_1 = require("tslib"); -const child_process_1 = require("child_process"); const events_1 = require("events"); const stream_1 = require("stream"); const byline = require("byline"); +const atom_1 = require("atom"); exports.CommandWithResponse = new Set([ "compileOnSaveAffectedFileList", "compileOnSaveEmitFile", @@ -149,13 +149,16 @@ class TypescriptServiceClient { if (!this.serverPromise) { this.serverPromise = new Promise((resolve, reject) => { // console.log("starting", this.tsServerPath) - const cp = child_process_1.spawn(this.tsServerPath, this.tsServerArgs); + const cp = new atom_1.BufferedNodeProcess({ + command: this.tsServerPath, + args: this.tsServerArgs, + }).process; cp.once("error", err => { - // console.log("tsserver starting failed with", err) + console.log("tsserver failed with", err); reject(err); }); cp.once("exit", code => { - // console.log("tsserver failed to start with code", code) + console.log("tsserver failed to start with code", code); reject({ code }); }); messageStream(cp.stdout).on("data", this.onMessage); diff --git a/lib/client/client.ts b/lib/client/client.ts index d24435946..f3667f572 100644 --- a/lib/client/client.ts +++ b/lib/client/client.ts @@ -1,8 +1,9 @@ -import {ChildProcess, spawn} from "child_process" import {EventEmitter} from "events" import {Transform, Readable} from "stream" import * as protocol from "typescript/lib/protocol" import byline = require("byline") +import {BufferedNodeProcess} from "atom" +import {ChildProcess} from "child_process" export const CommandWithResponse = new Set([ "compileOnSaveAffectedFileList", @@ -193,15 +194,18 @@ export class TypescriptServiceClient { this.serverPromise = new Promise((resolve, reject) => { // console.log("starting", this.tsServerPath) - const cp = spawn(this.tsServerPath, this.tsServerArgs) + const cp = new BufferedNodeProcess({ + command: this.tsServerPath, + args: this.tsServerArgs, + }).process as any as ChildProcess cp.once("error", err => { - // console.log("tsserver starting failed with", err) + console.log("tsserver failed with", err) reject(err) }) cp.once("exit", code => { - // console.log("tsserver failed to start with code", code) + console.log("tsserver failed to start with code", code) reject({code}) }) From 600e1d8f45a1fdec3c6e340e6af0cc3bc369bd37 Mon Sep 17 00:00:00 2001 From: Guntars Asmanis-Graham Date: Sat, 28 Jan 2017 20:23:38 -0500 Subject: [PATCH 60/70] Prepare 11.0.0 release --- package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/package.json b/package.json index 422a3bf4a..df9af3c62 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "atom-typescript-beta", - "version": "11.0.0-beta", + "version": "11.0.0", "main": "./dist/main/atomts", "preferGlobal": true, "description": "The only TypeScript plugin you will ever need.", From e0a920e7ea5a70c0ef97d0be5fd97e75064aa5f8 Mon Sep 17 00:00:00 2001 From: Guntars Asmanis-Graham Date: Sat, 28 Jan 2017 21:25:14 -0500 Subject: [PATCH 61/70] Translate between win32 and posix paths in errorPusher --- dist/main/atom/utils/fs.js | 4 +++- dist/main/errorPusher.js | 3 ++- lib/main/atom/utils/fs.ts | 7 +++++-- lib/main/errorPusher.ts | 5 +++-- lib/main/utils/fsUtil.ts | 0 5 files changed, 13 insertions(+), 6 deletions(-) delete mode 100644 lib/main/utils/fsUtil.ts diff --git a/dist/main/atom/utils/fs.js b/dist/main/atom/utils/fs.js index f691f5e28..ed4270dd6 100644 --- a/dist/main/atom/utils/fs.js +++ b/dist/main/atom/utils/fs.js @@ -2,12 +2,14 @@ * Wraps fs and path into a nice "consistentPath" API */ "use strict"; -/** we work with "/" for all paths (so does the typescript language service) */ 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... diff --git a/dist/main/errorPusher.js b/dist/main/errorPusher.js index d5c40bd20..4b255194b 100644 --- a/dist/main/errorPusher.js +++ b/dist/main/errorPusher.js @@ -9,11 +9,12 @@ class ErrorPusher { 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: "Error", text: diagnostic.text, - filePath: filePath, + filePath: _filePath, range: diagnostic.start ? utils_1.locationsToRange(diagnostic.start, diagnostic.end) : undefined }); } diff --git a/lib/main/atom/utils/fs.ts b/lib/main/atom/utils/fs.ts index b164ff4b2..37a901b1f 100644 --- a/lib/main/atom/utils/fs.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... diff --git a/lib/main/errorPusher.ts b/lib/main/errorPusher.ts index b6c674b0f..100ccf25a 100644 --- a/lib/main/errorPusher.ts +++ b/lib/main/errorPusher.ts @@ -1,7 +1,7 @@ import {debounce} from "lodash" import {Diagnostic} from "typescript/lib/protocol" import {Linter, LinterMessage} from "../typings/linter" -import {locationsToRange} from "./atom/utils" +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 { @@ -38,11 +38,12 @@ export class ErrorPusher { 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: "Error", text: diagnostic.text, - filePath: filePath, + filePath: _filePath, range: diagnostic.start ? locationsToRange(diagnostic.start, diagnostic.end) : undefined }) } diff --git a/lib/main/utils/fsUtil.ts b/lib/main/utils/fsUtil.ts deleted file mode 100644 index e69de29bb..000000000 From 32ee7be7a7395351c80a5b5ab7cb903e4ba6396b Mon Sep 17 00:00:00 2001 From: Guntars Asmanis-Graham Date: Sat, 28 Jan 2017 21:25:27 -0500 Subject: [PATCH 62/70] Prepare 11.0.1 release --- package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/package.json b/package.json index df9af3c62..f25d9229d 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "atom-typescript-beta", - "version": "11.0.0", + "version": "11.0.1", "main": "./dist/main/atomts", "preferGlobal": true, "description": "The only TypeScript plugin you will ever need.", From 6b507536df691803f76eca245673ee9ee66a95a5 Mon Sep 17 00:00:00 2001 From: dean Date: Wed, 15 Feb 2017 17:09:11 -0500 Subject: [PATCH 63/70] add return-to-declaration functionality --- dist/main/atom/commands/goToDeclaration.js | 25 ++++++++++++---- keymaps/atom-typescript.cson | 1 + lib/main/atom/commands/goToDeclaration.ts | 34 +++++++++++++++++----- menus/atomts-menus.cson | 1 + 4 files changed, 48 insertions(+), 13 deletions(-) diff --git a/dist/main/atom/commands/goToDeclaration.js b/dist/main/atom/commands/goToDeclaration.js index d757995fc..da6a70d2f 100644 --- a/dist/main/atom/commands/goToDeclaration.js +++ b/dist/main/atom/commands/goToDeclaration.js @@ -3,6 +3,13 @@ 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)) { @@ -11,6 +18,7 @@ registry_1.commands.set("typescript:go-to-declaration", deps => { const location = utils_1.getFilePathPosition(); const client = yield deps.getClient(location.file); const result = yield client.executeDefinition(location); + prevCursorPositions.push(location); if (result.body.length > 1) { simpleSelectionView_1.simpleSelectionView({ items: result.body, @@ -27,11 +35,18 @@ registry_1.commands.set("typescript:go-to-declaration", deps => { else { open(result.body[0]); } - function open(item) { - atom.workspace.open(item.file, { - initialLine: item.start.line - 1, - initialColumn: item.start.offset - 1 - }); + }); +}); +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 } + }); }); }); diff --git a/keymaps/atom-typescript.cson b/keymaps/atom-typescript.cson index 14fe2b473..8ba14fdfc 100644 --- a/keymaps/atom-typescript.cson +++ b/keymaps/atom-typescript.cson @@ -12,6 +12,7 @@ # Stronger bindings 'atom-workspace': 'f6': 'typescript:build' + 'f10': 'typescript:return-from-declaration' 'f12': 'typescript:go-to-declaration' 'ctrl-\'': 'typescript:sync' 'cmd-\'': 'typescript:sync' diff --git a/lib/main/atom/commands/goToDeclaration.ts b/lib/main/atom/commands/goToDeclaration.ts index 7bd8cca9c..d06334b86 100644 --- a/lib/main/atom/commands/goToDeclaration.ts +++ b/lib/main/atom/commands/goToDeclaration.ts @@ -2,6 +2,15 @@ import {commands} from "./registry" import {commandForTypeScript, getFilePathPosition} from "../utils" import {simpleSelectionView} from "../views/simpleSelectionView" +const prevCursorPositions:any[] = []; + +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)) { @@ -12,6 +21,8 @@ commands.set("typescript:go-to-declaration", deps => { const client = await deps.getClient(location.file) const result = await client.executeDefinition(location) + prevCursorPositions.push(location); + if (result.body!.length > 1) { simpleSelectionView({ items: result.body!, @@ -27,12 +38,19 @@ commands.set("typescript:go-to-declaration", deps => { } else { open(result.body![0]) } - - 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: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/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' } ] ] } From 805414d58180f8792e6027d0f3b2ceec027df094 Mon Sep 17 00:00:00 2001 From: dean Date: Mon, 20 Feb 2017 11:26:37 -0500 Subject: [PATCH 64/70] add type annotation. don't add prev cursor position if multi select isn't picked --- dist/main/atom/commands/goToDeclaration.js | 7 +++++-- lib/main/atom/commands/goToDeclaration.ts | 12 +++++++----- 2 files changed, 12 insertions(+), 7 deletions(-) diff --git a/dist/main/atom/commands/goToDeclaration.js b/dist/main/atom/commands/goToDeclaration.js index da6a70d2f..44c3d64f7 100644 --- a/dist/main/atom/commands/goToDeclaration.js +++ b/dist/main/atom/commands/goToDeclaration.js @@ -18,7 +18,6 @@ registry_1.commands.set("typescript:go-to-declaration", deps => { const location = utils_1.getFilePathPosition(); const client = yield deps.getClient(location.file); const result = yield client.executeDefinition(location); - prevCursorPositions.push(location); if (result.body.length > 1) { simpleSelectionView_1.simpleSelectionView({ items: result.body, @@ -29,10 +28,14 @@ registry_1.commands.set("typescript:go-to-declaration", deps => { `; }, filterKey: 'filePath', - confirmed: item => open(item) + confirmed: item => { + prevCursorPositions.push(location); + open(item); + } }); } else { + prevCursorPositions.push(location); open(result.body[0]); } }); diff --git a/lib/main/atom/commands/goToDeclaration.ts b/lib/main/atom/commands/goToDeclaration.ts index d06334b86..18892466f 100644 --- a/lib/main/atom/commands/goToDeclaration.ts +++ b/lib/main/atom/commands/goToDeclaration.ts @@ -1,8 +1,8 @@ import {commands} from "./registry" -import {commandForTypeScript, getFilePathPosition} from "../utils" +import {commandForTypeScript, getFilePathPosition, FileLocationQuery} from "../utils" import {simpleSelectionView} from "../views/simpleSelectionView" -const prevCursorPositions:any[] = []; +const prevCursorPositions:FileLocationQuery[] = []; function open(item: {file: string, start: {line: number, offset: number}}) { atom.workspace.open(item.file, { @@ -21,8 +21,6 @@ commands.set("typescript:go-to-declaration", deps => { const client = await deps.getClient(location.file) const result = await client.executeDefinition(location) - prevCursorPositions.push(location); - if (result.body!.length > 1) { simpleSelectionView({ items: result.body!, @@ -33,9 +31,13 @@ commands.set("typescript:go-to-declaration", deps => { ` }, filterKey: 'filePath', - confirmed: item => open(item) + confirmed: item => { + prevCursorPositions.push(location); + open(item) + } }) } else { + prevCursorPositions.push(location); open(result.body![0]) } } From 82f4b2a5011ef449d98847e51ef84c8c5fdf9cfc Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E5=B0=8F=E6=9E=97=E7=85=A7=E5=B9=B8?= Date: Tue, 21 Feb 2017 09:56:00 +0900 Subject: [PATCH 65/70] Update highlights.less Starting from Atom v1.13.0, the contents of atom-text-editor elements are no longer encapsulated within a shadow DOM boundary. This means you should stop using :host and ::shadow pseudo-selectors, and prepend all your syntax selectors with syntax--. To prevent breakage with existing style sheets, Atom will automatically upgrade the following selectors: atom-text-editor::shadow .highlights .atom-typescript-occurrence .region => atom-text-editor.editor .highlights .atom-typescript-occurrence .region Automatic translation of selectors will be removed in a few release cycles to minimize startup time. Please, make sure to upgrade the above selectors as soon as possible. --- styles/highlights.less | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/styles/highlights.less b/styles/highlights.less index db6615377..29df648b6 100644 --- a/styles/highlights.less +++ b/styles/highlights.less @@ -1,6 +1,6 @@ @import "ui-variables"; -atom-text-editor::shadow { +atom-text-editor.editor { .highlights { .atom-typescript-occurrence { .region { From cdfbf058415b6dae1c0124d408371f751d960bf2 Mon Sep 17 00:00:00 2001 From: Guntars Asmanis-Graham Date: Sun, 19 Mar 2017 18:31:53 -0400 Subject: [PATCH 66/70] Merge branch 'master' into use-tsserver --- dist/client/client.js | 1 + dist/client/clientResolver.js | 1 + dist/client/findServer.js | 1 + dist/hyperclickProvider.js | 1 + dist/main/atom/autoCompleteProvider.js | 7 +++--- dist/main/atom/commands/build.js | 1 + dist/main/atom/commands/checkAllFiles.js | 1 + dist/main/atom/commands/clearErrors.js | 1 + dist/main/atom/commands/findReferences.js | 1 + dist/main/atom/commands/formatCode.js | 3 ++- dist/main/atom/commands/goToDeclaration.js | 1 + dist/main/atom/commands/index.js | 1 + dist/main/atom/commands/registry.js | 1 + dist/main/atom/commands/renameRefactor.js | 1 + dist/main/atom/components/index.js | 1 + dist/main/atom/components/statusPanel.js | 1 + dist/main/atom/components/tsView.js | 1 + dist/main/atom/gotoHistory.js | 1 + dist/main/atom/tooltipManager.js | 12 ++++++---- dist/main/atom/utils/atom.js | 4 ++-- dist/main/atom/utils/fs.js | 1 + dist/main/atom/utils/index.js | 1 + dist/main/atom/utils/ts.js | 1 + dist/main/atom/views/lineMessageView.js | 1 + dist/main/atom/views/plainMessageView.js | 1 + dist/main/atom/views/renameView.js | 4 ++-- .../atom/views/simpleOverlaySelectionView.js | 2 +- dist/main/atom/views/simpleSelectionView.js | 1 + dist/main/atom/views/tooltipView.js | 1 + dist/main/atom/views/typeOverlayView.js | 1 + dist/main/atom/views/view.js | 1 + dist/main/atomts.js | 3 ++- dist/main/errorPusher.js | 1 + dist/main/lang/utils.js | 1 + dist/main/tsconfig/formatting.js | 1 + dist/main/typescriptBuffer.js | 3 ++- dist/main/typescriptEditorPane.js | 6 +++++ dist/main/utils/fsUtil.js | 0 lib/main/atom/tooltipManager.ts | 11 +++++---- lib/main/atomts.ts | 2 +- lib/main/typescriptEditorPane.ts | 6 +++++ lib/typings/typings.d.ts | 23 +++++-------------- package.json | 15 ++++-------- snippets/typescript-snippets.cson | 3 +++ styles/atomts-grammar-syntax.less | 23 +++++++++++-------- 45 files changed, 99 insertions(+), 56 deletions(-) delete mode 100644 dist/main/utils/fsUtil.js diff --git a/dist/client/client.js b/dist/client/client.js index f0b59db64..1ea996500 100644 --- a/dist/client/client.js +++ b/dist/client/client.js @@ -1,4 +1,5 @@ "use strict"; +Object.defineProperty(exports, "__esModule", { value: true }); const tslib_1 = require("tslib"); const events_1 = require("events"); const stream_1 = require("stream"); diff --git a/dist/client/clientResolver.js b/dist/client/clientResolver.js index c5a713654..afc099d2d 100644 --- a/dist/client/clientResolver.js +++ b/dist/client/clientResolver.js @@ -1,4 +1,5 @@ "use strict"; +Object.defineProperty(exports, "__esModule", { value: true }); const client_1 = require("./client"); const events = require("events"); const path = require("path"); diff --git a/dist/client/findServer.js b/dist/client/findServer.js index 602c92b84..27adf1b26 100644 --- a/dist/client/findServer.js +++ b/dist/client/findServer.js @@ -1,4 +1,5 @@ "use strict"; +Object.defineProperty(exports, "__esModule", { value: true }); const fs = require("fs"); const path = require("path"); /** Recursively search all directories rooted at the argument and find all typescript modules */ diff --git a/dist/hyperclickProvider.js b/dist/hyperclickProvider.js index b5d568c91..cd03a33d7 100644 --- a/dist/hyperclickProvider.js +++ b/dist/hyperclickProvider.js @@ -1,4 +1,5 @@ "use strict"; +Object.defineProperty(exports, "__esModule", { value: true }); const TS_GRAMMARS = new Set(["source.ts", "source.tsx"]); exports.providerName = "typescript-hyperclick-provider"; exports.wordRegExp = /([A-Za-z0-9_])+|['"`](\\.|[^'"`\\\\])*['"`]/g; diff --git a/dist/main/atom/autoCompleteProvider.js b/dist/main/atom/autoCompleteProvider.js index 51f2fdb80..cc2ade743 100644 --- a/dist/main/atom/autoCompleteProvider.js +++ b/dist/main/atom/autoCompleteProvider.js @@ -1,4 +1,5 @@ "use strict"; +Object.defineProperty(exports, "__esModule", { value: true }); const tslib_1 = require("tslib"); const utils_1 = require("./utils"); const Atom = require("atom"); @@ -28,7 +29,7 @@ class AutocompleteProvider { } } const client = yield this.clientResolver.get(location.file); - const completions = yield client.executeCompletions(tslib_1.__assign({ prefix }, location)); + const completions = yield client.executeCompletions(Object.assign({ prefix }, location)); const suggestions = completions.body.map(entry => ({ text: entry.name, leftLabel: entry.kind, @@ -84,13 +85,13 @@ class AutocompleteProvider { // Get additional details for the first few suggestions yield this.getAdditionalDetails(suggestions.slice(0, 10), location); const trimmed = prefix.trim(); - return suggestions.map(suggestion => (tslib_1.__assign({ replacementPrefix: getReplacementPrefix(prefix, trimmed, suggestion.text) }, suggestion))); + 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(tslib_1.__assign({ entryNames: suggestions.map(s => s.text) }, location)); + 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; diff --git a/dist/main/atom/commands/build.js b/dist/main/atom/commands/build.js index 827a32184..87387fb4f 100644 --- a/dist/main/atom/commands/build.js +++ b/dist/main/atom/commands/build.js @@ -1,4 +1,5 @@ "use strict"; +Object.defineProperty(exports, "__esModule", { value: true }); const tslib_1 = require("tslib"); const registry_1 = require("./registry"); const utils_1 = require("../utils"); diff --git a/dist/main/atom/commands/checkAllFiles.js b/dist/main/atom/commands/checkAllFiles.js index 3f1bc58eb..de46df3b1 100644 --- a/dist/main/atom/commands/checkAllFiles.js +++ b/dist/main/atom/commands/checkAllFiles.js @@ -1,4 +1,5 @@ "use strict"; +Object.defineProperty(exports, "__esModule", { value: true }); const tslib_1 = require("tslib"); const registry_1 = require("./registry"); const utils_1 = require("../utils"); diff --git a/dist/main/atom/commands/clearErrors.js b/dist/main/atom/commands/clearErrors.js index 642c79800..189b3f9ae 100644 --- a/dist/main/atom/commands/clearErrors.js +++ b/dist/main/atom/commands/clearErrors.js @@ -1,4 +1,5 @@ "use strict"; +Object.defineProperty(exports, "__esModule", { value: true }); const registry_1 = require("./registry"); registry_1.commands.set("typescript:clear-errors", deps => { return e => { diff --git a/dist/main/atom/commands/findReferences.js b/dist/main/atom/commands/findReferences.js index 3d7af00aa..b1b8e3e32 100644 --- a/dist/main/atom/commands/findReferences.js +++ b/dist/main/atom/commands/findReferences.js @@ -1,4 +1,5 @@ "use strict"; +Object.defineProperty(exports, "__esModule", { value: true }); const tslib_1 = require("tslib"); const registry_1 = require("./registry"); const utils_1 = require("../utils"); diff --git a/dist/main/atom/commands/formatCode.js b/dist/main/atom/commands/formatCode.js index 0fe1e04c1..0a72694e8 100644 --- a/dist/main/atom/commands/formatCode.js +++ b/dist/main/atom/commands/formatCode.js @@ -1,4 +1,5 @@ "use strict"; +Object.defineProperty(exports, "__esModule", { value: true }); const tslib_1 = require("tslib"); const registry_1 = require("./registry"); const utils_1 = require("../utils"); @@ -34,7 +35,7 @@ registry_1.commands.set("typescript:format-code", deps => { }; // Collect all edits together so we can update everything in a single transaction for (const range of ranges) { - const result = yield client.executeFormat(tslib_1.__assign({}, range, { options, file: filePath })); + const result = yield client.executeFormat(Object.assign({}, range, { options, file: filePath })); if (result.body) { edits.push(...result.body); } diff --git a/dist/main/atom/commands/goToDeclaration.js b/dist/main/atom/commands/goToDeclaration.js index d757995fc..858fc6812 100644 --- a/dist/main/atom/commands/goToDeclaration.js +++ b/dist/main/atom/commands/goToDeclaration.js @@ -1,4 +1,5 @@ "use strict"; +Object.defineProperty(exports, "__esModule", { value: true }); const tslib_1 = require("tslib"); const registry_1 = require("./registry"); const utils_1 = require("../utils"); diff --git a/dist/main/atom/commands/index.js b/dist/main/atom/commands/index.js index dcd56af91..c2d5ae8ad 100644 --- a/dist/main/atom/commands/index.js +++ b/dist/main/atom/commands/index.js @@ -9,6 +9,7 @@ // import {simpleSelectionView} from "../views/simpleSelectionView"; // import escapeHtml = require('escape-html'); "use strict"; +Object.defineProperty(exports, "__esModule", { value: true }); // Load all the web components // export * from "../components/componentRegistry"; const registry_1 = require("./registry"); diff --git a/dist/main/atom/commands/registry.js b/dist/main/atom/commands/registry.js index ea2350e74..1e0621536 100644 --- a/dist/main/atom/commands/registry.js +++ b/dist/main/atom/commands/registry.js @@ -1,4 +1,5 @@ "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. diff --git a/dist/main/atom/commands/renameRefactor.js b/dist/main/atom/commands/renameRefactor.js index acec36009..3b7ea0a78 100644 --- a/dist/main/atom/commands/renameRefactor.js +++ b/dist/main/atom/commands/renameRefactor.js @@ -1,4 +1,5 @@ "use strict"; +Object.defineProperty(exports, "__esModule", { value: true }); const tslib_1 = require("tslib"); const registry_1 = require("./registry"); const utils_1 = require("../utils"); diff --git a/dist/main/atom/components/index.js b/dist/main/atom/components/index.js index 1819bc7eb..17e549e07 100644 --- a/dist/main/atom/components/index.js +++ b/dist/main/atom/components/index.js @@ -2,4 +2,5 @@ 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")); diff --git a/dist/main/atom/components/statusPanel.js b/dist/main/atom/components/statusPanel.js index 6db5dfa02..b463886c2 100644 --- a/dist/main/atom/components/statusPanel.js +++ b/dist/main/atom/components/statusPanel.js @@ -1,4 +1,5 @@ "use strict"; +Object.defineProperty(exports, "__esModule", { value: true }); const dom = require("jsx-render-dom"); const path_1 = require("path"); const utils_1 = require("../utils"); diff --git a/dist/main/atom/components/tsView.js b/dist/main/atom/components/tsView.js index f7105537d..1dc4809e2 100644 --- a/dist/main/atom/components/tsView.js +++ b/dist/main/atom/components/tsView.js @@ -1,6 +1,7 @@ // Some docs // http://www.html5rocks.com/en/tutorials/webcomponents/customelements/ (look at lifecycle callback methods) "use strict"; +Object.defineProperty(exports, "__esModule", { value: true }); class TsView extends HTMLElement { createdCallback() { var preview = this.innerText; diff --git a/dist/main/atom/gotoHistory.js b/dist/main/atom/gotoHistory.js index d3f5566c8..66e061d6f 100644 --- a/dist/main/atom/gotoHistory.js +++ b/dist/main/atom/gotoHistory.js @@ -1,4 +1,5 @@ "use strict"; +Object.defineProperty(exports, "__esModule", { value: true }); exports.errorsInOpenFiles = { members: [] }; exports.buildOutput = { members: [] }; exports.referencesOutput = { members: [] }; diff --git a/dist/main/atom/tooltipManager.js b/dist/main/atom/tooltipManager.js index 533ff91d8..239556cfb 100644 --- a/dist/main/atom/tooltipManager.js +++ b/dist/main/atom/tooltipManager.js @@ -1,6 +1,7 @@ // Inspiration : https://atom.io/packages/ide-haskell // and https://atom.io/packages/ide-flow "use strict"; +Object.defineProperty(exports, "__esModule", { value: true }); const tslib_1 = require("tslib"); const atomUtils = require("./utils"); ///ts:import:generated const atomts_1 = require("../atomts"); @@ -22,6 +23,9 @@ 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)) @@ -39,7 +43,7 @@ function attach(editorView, editor) { var lastExprTypeBufferPt; 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; @@ -57,9 +61,9 @@ function attach(editorView, editor) { 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]); diff --git a/dist/main/atom/utils/atom.js b/dist/main/atom/utils/atom.js index 14d9ca3a4..006edaab8 100644 --- a/dist/main/atom/utils/atom.js +++ b/dist/main/atom/utils/atom.js @@ -1,5 +1,5 @@ "use strict"; -const tslib_1 = require("tslib"); +Object.defineProperty(exports, "__esModule", { value: true }); const Atom = require("atom"); const fs = require("fs"); const path = require("path"); @@ -68,7 +68,7 @@ function onDiskAndTsRelated(editor) { exports.onDiskAndTsRelated = onDiskAndTsRelated; function getFilePathPosition() { const editor = atom.workspace.getActiveTextEditor(); - return tslib_1.__assign({ file: editor.getPath() }, getEditorPosition(editor)); + return Object.assign({ file: editor.getPath() }, getEditorPosition(editor)); } exports.getFilePathPosition = getFilePathPosition; function getFilePath() { diff --git a/dist/main/atom/utils/fs.js b/dist/main/atom/utils/fs.js index ed4270dd6..35d4fcfa8 100644 --- a/dist/main/atom/utils/fs.js +++ b/dist/main/atom/utils/fs.js @@ -2,6 +2,7 @@ * Wraps fs and path into a nice "consistentPath" API */ "use strict"; +Object.defineProperty(exports, "__esModule", { value: true }); function consistentPath(filePath) { return filePath.split('\\').join('/'); } diff --git a/dist/main/atom/utils/index.js b/dist/main/atom/utils/index.js index bad9d14c2..4d2daf449 100644 --- a/dist/main/atom/utils/index.js +++ b/dist/main/atom/utils/index.js @@ -2,6 +2,7 @@ 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")); diff --git a/dist/main/atom/utils/ts.js b/dist/main/atom/utils/ts.js index 8709128e3..044b59a5f 100644 --- a/dist/main/atom/utils/ts.js +++ b/dist/main/atom/utils/ts.js @@ -1,4 +1,5 @@ "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); diff --git a/dist/main/atom/views/lineMessageView.js b/dist/main/atom/views/lineMessageView.js index 0b229dbf1..42a01a2e8 100644 --- a/dist/main/atom/views/lineMessageView.js +++ b/dist/main/atom/views/lineMessageView.js @@ -1,4 +1,5 @@ "use strict"; +Object.defineProperty(exports, "__esModule", { value: true }); const view = require("./view"); var $ = view.$; class LineMessageView extends view.View { diff --git a/dist/main/atom/views/plainMessageView.js b/dist/main/atom/views/plainMessageView.js index cb87c7e6f..f59c8deff 100644 --- a/dist/main/atom/views/plainMessageView.js +++ b/dist/main/atom/views/plainMessageView.js @@ -1,4 +1,5 @@ "use strict"; +Object.defineProperty(exports, "__esModule", { value: true }); const view = require("./view"); class PlainMessageView extends view.View { static content() { diff --git a/dist/main/atom/views/renameView.js b/dist/main/atom/views/renameView.js index 7eca7752c..bd34f442d 100644 --- a/dist/main/atom/views/renameView.js +++ b/dist/main/atom/views/renameView.js @@ -1,5 +1,5 @@ "use strict"; -const tslib_1 = require("tslib"); +Object.defineProperty(exports, "__esModule", { value: true }); const view = require("./view"); var $ = view.$; var html = require('../../../../views/renameView.html'); @@ -66,7 +66,7 @@ class RenameView extends view.View { // Show the dialog and resolve the promise with the entered string showRenameDialog(options) { return new Promise((resolve, reject) => { - this.renameThis(tslib_1.__assign({}, options, { onCancel: reject, onCommit: resolve })); + this.renameThis(Object.assign({}, options, { onCancel: reject, onCommit: resolve })); }); } } diff --git a/dist/main/atom/views/simpleOverlaySelectionView.js b/dist/main/atom/views/simpleOverlaySelectionView.js index f54a4e050..53a3cf403 100644 --- a/dist/main/atom/views/simpleOverlaySelectionView.js +++ b/dist/main/atom/views/simpleOverlaySelectionView.js @@ -3,6 +3,7 @@ * Only one of these bad boys is allowed on the screen at one time */ "use strict"; +Object.defineProperty(exports, "__esModule", { value: true }); var singleton; function default_1(options, editor) { if (!singleton) @@ -15,7 +16,6 @@ function default_1(options, editor) { singleton.show(); return singleton; } -Object.defineProperty(exports, "__esModule", { value: true }); exports.default = default_1; /** * Various Utility section diff --git a/dist/main/atom/views/simpleSelectionView.js b/dist/main/atom/views/simpleSelectionView.js index 8744865b9..c42c7feda 100644 --- a/dist/main/atom/views/simpleSelectionView.js +++ b/dist/main/atom/views/simpleSelectionView.js @@ -3,6 +3,7 @@ * Only one of these bad boys is allowed on the screen at one time */ "use strict"; +Object.defineProperty(exports, "__esModule", { value: true }); var singleton; function simpleSelectionView(options) { if (!singleton) diff --git a/dist/main/atom/views/tooltipView.js b/dist/main/atom/views/tooltipView.js index d6a906878..a5e728220 100644 --- a/dist/main/atom/views/tooltipView.js +++ b/dist/main/atom/views/tooltipView.js @@ -1,4 +1,5 @@ "use strict"; +Object.defineProperty(exports, "__esModule", { value: true }); const view = require("./view"); var $ = view.$; class TooltipView extends view.View { diff --git a/dist/main/atom/views/typeOverlayView.js b/dist/main/atom/views/typeOverlayView.js index c9d0138f2..839699602 100644 --- a/dist/main/atom/views/typeOverlayView.js +++ b/dist/main/atom/views/typeOverlayView.js @@ -1,4 +1,5 @@ "use strict"; +Object.defineProperty(exports, "__esModule", { value: true }); const escapeHtml = require("escape-html"); function create(type, comment) { let overlayHTML = ` diff --git a/dist/main/atom/views/view.js b/dist/main/atom/views/view.js index c5d4ec88f..11c6ebcc5 100644 --- a/dist/main/atom/views/view.js +++ b/dist/main/atom/views/view.js @@ -1,4 +1,5 @@ "use strict"; +Object.defineProperty(exports, "__esModule", { value: true }); const sp = require("atom-space-pen-views"); class View extends sp.View { constructor(options) { diff --git a/dist/main/atomts.js b/dist/main/atomts.js index aeade4a8e..fffce22f7 100644 --- a/dist/main/atomts.js +++ b/dist/main/atomts.js @@ -1,4 +1,5 @@ "use strict"; +Object.defineProperty(exports, "__esModule", { value: true }); const tslib_1 = require("tslib"); const Atom = require("atom"); const atomConfig = require("./atom/atomConfig"); @@ -25,7 +26,7 @@ const commands_1 = require("./atom/commands"); let linter; let statusBar; function activate(state) { - require('atom-package-deps').install('atom-typescript-beta').then(() => { + require('atom-package-deps').install('atom-typescript-beta', true).then(() => { let statusPriority = 100; for (const panel of statusBar.getRightTiles()) { if (panel.getItem().tagName === "GRAMMAR-SELECTOR-STATUS") { diff --git a/dist/main/errorPusher.js b/dist/main/errorPusher.js index 4b255194b..5964d1b23 100644 --- a/dist/main/errorPusher.js +++ b/dist/main/errorPusher.js @@ -1,4 +1,5 @@ "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 */ diff --git a/dist/main/lang/utils.js b/dist/main/lang/utils.js index 83e66e6d4..edcb605c9 100644 --- a/dist/main/lang/utils.js +++ b/dist/main/lang/utils.js @@ -12,6 +12,7 @@ // See the License for the specific language governing permissions and // limitations under the License. 'use strict'; +Object.defineProperty(exports, "__esModule", { value: true }); const path = require("path"); function mapValues(map) { return Object.keys(map).reduce((result, key) => { diff --git a/dist/main/tsconfig/formatting.js b/dist/main/tsconfig/formatting.js index ec5df09de..331a4f10e 100644 --- a/dist/main/tsconfig/formatting.js +++ b/dist/main/tsconfig/formatting.js @@ -1,4 +1,5 @@ "use strict"; +Object.defineProperty(exports, "__esModule", { value: true }); /** * Maintainance: * When a new option is added add it to: diff --git a/dist/main/typescriptBuffer.js b/dist/main/typescriptBuffer.js index 45aae6ea6..0403c9dca 100644 --- a/dist/main/typescriptBuffer.js +++ b/dist/main/typescriptBuffer.js @@ -1,4 +1,5 @@ "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). @@ -45,7 +46,7 @@ class TypescriptBuffer { endLine: start.row + oldExtent.row + 1, endOffset: (oldExtent.row === 0 ? start.column + oldExtent.column : oldExtent.column) + 1 }; - yield client.executeChange(tslib_1.__assign({}, end, { file: filePath, line: start.row + 1, offset: start.column + 1, insertString: newText })); + yield client.executeChange(Object.assign({}, end, { file: filePath, line: start.row + 1, offset: start.column + 1, insertString: newText })); } this.events.emit("changed"); }); diff --git a/dist/main/typescriptEditorPane.js b/dist/main/typescriptEditorPane.js index f8b0b3671..50c7c5c40 100644 --- a/dist/main/typescriptEditorPane.js +++ b/dist/main/typescriptEditorPane.js @@ -1,4 +1,5 @@ "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"); @@ -112,12 +113,17 @@ class TypescriptEditorPane { .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); } diff --git a/dist/main/utils/fsUtil.js b/dist/main/utils/fsUtil.js deleted file mode 100644 index e69de29bb..000000000 diff --git a/lib/main/atom/tooltipManager.ts b/lib/main/atom/tooltipManager.ts index bf83b292b..ebe7f4165 100644 --- a/lib/main/atom/tooltipManager.ts +++ b/lib/main/atom/tooltipManager.ts @@ -24,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; @@ -44,7 +47,7 @@ export function attach(editorView: JQuery, editor: AtomCore.IEditor) { 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; @@ -66,9 +69,9 @@ export function attach(editorView: JQuery, editor: AtomCore.IEditor) { 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]); diff --git a/lib/main/atomts.ts b/lib/main/atomts.ts index 091f4e3d1..6ee3db4b1 100644 --- a/lib/main/atomts.ts +++ b/lib/main/atomts.ts @@ -31,7 +31,7 @@ let statusBar: StatusBar interface PackageState {} export function activate(state: PackageState) { - require('atom-package-deps').install('atom-typescript-beta').then(() => { + require('atom-package-deps').install('atom-typescript-beta', true).then(() => { let statusPriority = 100 for (const panel of statusBar.getRightTiles()) { diff --git a/lib/main/typescriptEditorPane.ts b/lib/main/typescriptEditorPane.ts index 54f130563..ed14fa949 100644 --- a/lib/main/typescriptEditorPane.ts +++ b/lib/main/typescriptEditorPane.ts @@ -46,6 +46,11 @@ export class TypescriptEditorPane implements AtomCore.Disposable { 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) })) @@ -54,6 +59,7 @@ export class TypescriptEditorPane implements AtomCore.Disposable { } dispose() { + this.editor.element.classList.remove('typescript-editor') this.subscriptions.dispose() this.opts.onDispose(this) } diff --git a/lib/typings/typings.d.ts b/lib/typings/typings.d.ts index c0d18a10b..c16c4872a 100644 --- a/lib/typings/typings.d.ts +++ b/lib/typings/typings.d.ts @@ -17,16 +17,6 @@ declare module 'escape-html' { 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 'atom-space-pen-views' { import atom = require('atom'); export class SelectListView extends atom.SelectListView { } @@ -35,13 +25,6 @@ declare module 'atom-space-pen-views' { export var $: JQueryStatic; } -declare module 'basarat-text-buffer' { - var ctor: { - new (content: string): TextBuffer.ITextBuffer; - }; - export = ctor; -} - interface EmitOutput { sourceFileName: string; outputFiles: string[]; @@ -129,3 +112,9 @@ interface ReferenceDetails { position: EditorPosition preview: string; } + +declare module AtomCore { + export interface IEditor { + element: any; + } +} diff --git a/package.json b/package.json index f25d9229d..c80b6388b 100644 --- a/package.json +++ b/package.json @@ -50,20 +50,11 @@ "url": "https://github.com/TypeStrong/atom-typescript/pull/1166" }, "dependencies": { - "@types/atom": "0.0.35", - "@types/byline": "^4.2.31", - "@types/lodash": "^4.14.51", - "@types/resolve": "0.0.4", - "atom-package-deps": "^2.0.3", + "atom-package-deps": "4.4.1", "atom-space-pen-views": "^2.0.4", - "basarat-text-buffer": "6.0.0", "byline": "^5.0.0", - "byots": "2.2.0-dev.20161129.23.20", - "detect-indent": "^4.0.0", - "detect-newline": "^2.1.0", "emissary": "^1.3.3", "escape-html": "^1.0.1", - "findup": "^0.1.5", "fuzzaldrin": "^2.1.0", "jsx-render-dom": "0.1.2", "lodash": "^4.17.2", @@ -74,6 +65,10 @@ "xtend": "^4.0.0" }, "devDependencies": { + "@types/atom": "0.0.35", + "@types/byline": "^4.2.31", + "@types/lodash": "^4.14.51", + "@types/resolve": "0.0.4", "@types/cson": "0.0.30", "cson": "^3.0.2", "mz": "^2.1.0", 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/atomts-grammar-syntax.less b/styles/atomts-grammar-syntax.less index ef7402d33..9de621488 100644 --- a/styles/atomts-grammar-syntax.less +++ b/styles/atomts-grammar-syntax.less @@ -1,11 +1,16 @@ -atom-text-editor { - .source.ts, - .source.tsx { - .require.path, .reference.path, .es6import.path, .amd.path { - text-decoration: underline; - } - .keyword.debugger { - background-color: lime; - } +atom-text-editor.editor { + .syntax--source.syntax--ts, + .syntax--source.syntax--tsx { + .syntax--import-equals, + .syntax--import, + .syntax--triple-slash { + .syntax--string { + text-decoration: underline; + } } + + .syntax--keyword.syntax--debugger { + background-color: lime; + } + } } From 02eddd48ca03b5f309d13ad36b6da247f016ec7d Mon Sep 17 00:00:00 2001 From: Guntars Asmanis-Graham Date: Sun, 19 Mar 2017 19:02:14 -0400 Subject: [PATCH 67/70] EditorPane#client can actually be undefined too fixes #1213 --- dist/main/atomts.js | 3 ++- dist/main/typescriptEditorPane.js | 11 +++++++++-- lib/main/atomts.ts | 3 ++- lib/main/typescriptEditorPane.ts | 16 +++++++++++++--- 4 files changed, 26 insertions(+), 7 deletions(-) diff --git a/dist/main/atomts.js b/dist/main/atomts.js index fffce22f7..7e645cb64 100644 --- a/dist/main/atomts.js +++ b/dist/main/atomts.js @@ -72,7 +72,8 @@ function activate(state) { }); let activePane; const onSave = lodash_1.debounce((pane) => { - console.log("checking errors for all panes for", pane.filePath); + if (!pane.client) + return; const files = panes .sort((a, b) => a.activeAt - b.activeAt) .filter(_pane => _pane.filePath && _pane.isTypescript && _pane.client === pane.client) diff --git a/dist/main/typescriptEditorPane.js b/dist/main/typescriptEditorPane.js index 50c7c5c40..8f8802768 100644 --- a/dist/main/typescriptEditorPane.js +++ b/dist/main/typescriptEditorPane.js @@ -33,6 +33,8 @@ class TypescriptEditorPane { this.opts.statusPanel.setTsConfigPath(this.configFile); }; this.onChanged = () => { + if (!this.client) + return; this.opts.statusPanel.setBuildStatus(undefined); this.client.executeGetErr({ files: [this.filePath], @@ -44,6 +46,8 @@ class TypescriptEditorPane { 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, @@ -134,7 +138,10 @@ class TypescriptEditorPane { } compileOnSave() { return tslib_1.__awaiter(this, void 0, void 0, function* () { - const result = yield this.client.executeCompileOnSaveAffectedFileList({ + const { client } = this; + if (!client) + return; + const result = yield client.executeCompileOnSaveAffectedFileList({ file: this.filePath }); this.opts.statusPanel.setBuildStatus(undefined); @@ -143,7 +150,7 @@ class TypescriptEditorPane { return; } try { - const promises = fileNames.map(file => this.client.executeCompileOnSaveEmitFile({ file })); + 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"); diff --git a/lib/main/atomts.ts b/lib/main/atomts.ts index 6ee3db4b1..1b18edd8b 100644 --- a/lib/main/atomts.ts +++ b/lib/main/atomts.ts @@ -87,7 +87,8 @@ export function activate(state: PackageState) { let activePane: TypescriptEditorPane | undefined const onSave = debounce((pane: TypescriptEditorPane) => { - console.log("checking errors for all panes for", pane.filePath) + if (!pane.client) + return const files = panes .sort((a, b) => a.activeAt - b.activeAt) diff --git a/lib/main/typescriptEditorPane.ts b/lib/main/typescriptEditorPane.ts index ed14fa949..162d48e23 100644 --- a/lib/main/typescriptEditorPane.ts +++ b/lib/main/typescriptEditorPane.ts @@ -19,7 +19,7 @@ export class TypescriptEditorPane implements AtomCore.Disposable { activeAt: number buffer: TypescriptBuffer - client: TypescriptServiceClient + client?: TypescriptServiceClient // Path to the project's tsconfig.json configFile: string = "" @@ -86,6 +86,9 @@ export class TypescriptEditorPane implements AtomCore.Disposable { } onChanged = () => { + if (!this.client) + return + this.opts.statusPanel.setBuildStatus(undefined) this.client.executeGetErr({ @@ -106,6 +109,9 @@ export class TypescriptEditorPane implements AtomCore.Disposable { } updateMarkers = debounce(() => { + if (!this.client) + return + const pos = this.editor.getLastCursor().getBufferPosition() this.client.executeOccurances({ @@ -185,7 +191,11 @@ export class TypescriptEditorPane implements AtomCore.Disposable { } async compileOnSave() { - const result = await this.client.executeCompileOnSaveAffectedFileList({ + const {client} = this + if (!client) + return + + const result = await client.executeCompileOnSaveAffectedFileList({ file: this.filePath }) @@ -198,7 +208,7 @@ export class TypescriptEditorPane implements AtomCore.Disposable { } try { - const promises = fileNames.map(file => this.client.executeCompileOnSaveEmitFile({file})) + const promises = fileNames.map(file => client.executeCompileOnSaveEmitFile({file})) const saved = await Promise.all(promises) if (!saved.every(res => res.body)) { From 09eda7449fcd95bf9f7d664256610b8a925cfc4f Mon Sep 17 00:00:00 2001 From: Guntars Asmanis-Graham Date: Sun, 19 Mar 2017 19:39:24 -0400 Subject: [PATCH 68/70] Update typescript and enable strict mode --- dist/client/findServer.js | 81 --------------------- dist/main/atom/tooltipManager.js | 4 +- dist/main/atom/views/lineMessageView.js | 39 +++++----- lib/client/client.ts | 18 ++--- lib/client/findServer.ts | 95 ------------------------- lib/main/atom/autoCompleteProvider.ts | 7 +- lib/main/atom/commands/build.ts | 2 +- lib/main/atom/commands/checkAllFiles.ts | 2 +- lib/main/atom/commands/registry.ts | 2 +- lib/main/atom/components/tsView.ts | 4 +- lib/main/atom/tooltipManager.ts | 8 +-- lib/main/atom/utils/ts.ts | 2 +- lib/main/atom/views/lineMessageView.ts | 10 +-- lib/main/atom/views/renameView.ts | 2 +- lib/main/atom/views/typeOverlayView.ts | 2 +- lib/main/atomts.ts | 2 +- lib/main/typescriptBuffer.ts | 2 +- lib/main/typescriptEditorPane.ts | 2 +- lib/tsconfig.json | 6 +- package.json | 5 +- 20 files changed, 61 insertions(+), 234 deletions(-) delete mode 100644 dist/client/findServer.js delete mode 100644 lib/client/findServer.ts diff --git a/dist/client/findServer.js b/dist/client/findServer.js deleted file mode 100644 index 27adf1b26..000000000 --- a/dist/client/findServer.js +++ /dev/null @@ -1,81 +0,0 @@ -"use strict"; -Object.defineProperty(exports, "__esModule", { value: true }); -const fs = require("fs"); -const path = require("path"); -/** Recursively search all directories rooted at the argument and find all typescript modules */ -function findTypescriptServers(root) { - const results = []; - if (!path.isAbsolute(root)) { - throw new Error("Argument should be an absolute path"); - } - return new Promise(resolve => { - walk(root, () => { - resolve(results); - }); - }); - function walk(dir, done) { - fs.readdir(dir, (err, files) => { - if (err || files.length === 0) - return done(); - const doneEntry = after(files.length, () => { - done(); - }); - for (const entry of files) { - if (entry === "node_modules") { - fs.stat(path.join(dir, entry, "typescript"), err => { - if (err) { - doneEntry(); - } - else { - getServerInfo(dir, (err, info) => { - if (info) - results.push(info); - doneEntry(); - }); - } - }); - } - else if (entry === ".git" || entry === "bower_components") { - doneEntry(); - } - else { - walk(path.join(dir, entry), doneEntry); - } - } - }); - } -} -exports.findTypescriptServers = findTypescriptServers; -/** Get info about the tsserver at the prefix */ -function getServerInfo(prefix, callback) { - const tsDir = path.join(prefix, "node_modules", "typescript"); - fs.readFile(path.join(tsDir, "package.json"), "utf8", (err, pkg) => { - if (err) - return callback(err, null); - try { - const version = JSON.parse(pkg).version; - const tsServerPath = path.join(tsDir, "bin", "tsserver"); - fs.stat(tsServerPath, (err, stat) => { - if (err) - return callback(err, null); - callback(null, { - binPath: tsServerPath, - prefix, - version - }); - }); - } - catch (error) { - callback(error, null); - } - }); -} -function after(count, callback) { - let called = 0; - return function () { - called++; - if (called >= count) { - callback.apply(this, arguments); - } - }; -} diff --git a/dist/main/atom/tooltipManager.js b/dist/main/atom/tooltipManager.js index 239556cfb..548f87335 100644 --- a/dist/main/atom/tooltipManager.js +++ b/dist/main/atom/tooltipManager.js @@ -51,8 +51,8 @@ function attach(editorView, editor) { 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) { diff --git a/dist/main/atom/views/lineMessageView.js b/dist/main/atom/views/lineMessageView.js index 42a01a2e8..ebd328a78 100644 --- a/dist/main/atom/views/lineMessageView.js +++ b/dist/main/atom/views/lineMessageView.js @@ -3,6 +3,27 @@ Object.defineProperty(exports, "__esModule", { value: true }); const view = require("./view"); var $ = view.$; class LineMessageView extends view.View { + constructor() { + super(...arguments); + this.goToLine = () => { + this.options.goToLine(this.options.file, this.options.line, this.options.col); + }; + this.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: (element) => { + $(element) + .css('cursor', 'pointer') + .click(this.goToLine); + } + }; + }; + } static content() { return this.div({ class: 'line-message' @@ -39,23 +60,5 @@ class LineMessageView extends view.View { 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) - }; - } } exports.LineMessageView = LineMessageView; diff --git a/lib/client/client.ts b/lib/client/client.ts index f3667f572..d23d395b7 100644 --- a/lib/client/client.ts +++ b/lib/client/client.ts @@ -27,8 +27,8 @@ export class TypescriptServiceClient { callbacks: { [seq: number]: { name: string - reject(res) - resolve(res) + reject(err: Error): void + resolve(res: protocol.Response): void started: number } } = {} @@ -47,7 +47,7 @@ export class TypescriptServiceClient { readonly tsServerArgs = [] readonly version: string - constructor(tsServerPath: string, version) { + constructor(tsServerPath: string, version: string) { this.tsServerPath = tsServerPath this.version = version } @@ -110,7 +110,7 @@ export class TypescriptServiceClient { return this.execute("saveto", args) } - private async execute(command: string, args) { + private async execute(command: string, args: any) { if (!this.serverPromise) { throw new Error("Server is not running") } @@ -161,10 +161,10 @@ export class TypescriptServiceClient { } } - private sendRequest(cp: ChildProcess, command: string, args, expectResponse: true): Promise - private sendRequest(cp: ChildProcess, command: string, args, expectResponse: false): undefined - private sendRequest(cp: ChildProcess, command: string, args, expectResponse: boolean): Promise | undefined - private sendRequest(cp: ChildProcess, command: string, args, expectResponse: boolean): Promise | undefined { + 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++, @@ -248,7 +248,7 @@ class MessageStream extends Transform { super({objectMode: true}) } - _transform(line, encoding, callback) { + _transform(line: string, encoding: string, callback: Function) { if (this.lineCount % 2 === 0) { this.push(JSON.parse(line)) } diff --git a/lib/client/findServer.ts b/lib/client/findServer.ts deleted file mode 100644 index d43e098ca..000000000 --- a/lib/client/findServer.ts +++ /dev/null @@ -1,95 +0,0 @@ -import * as fs from "fs" -import * as path from "path" - -export interface Server { - /** Path the the tsserver executable */ - binPath: string - - /* Path where the node_modules directory is that contains the typescript installation */ - prefix: string - - /* Version of Typescript */ - version: string -} - -/** Recursively search all directories rooted at the argument and find all typescript modules */ -export function findTypescriptServers(root: string): Promise { - const results: Server[] = [] - - if (!path.isAbsolute(root)) { - throw new Error("Argument should be an absolute path") - } - - return new Promise(resolve => { - walk(root, () => { - resolve(results) - }) - }) - - function walk(dir: string, done: Function) { - fs.readdir(dir, (err, files) => { - if (err || files.length === 0) return done() - - const doneEntry = after(files.length, () => { - done() - }) - - for (const entry of files) { - if (entry === "node_modules") { - fs.stat(path.join(dir, entry, "typescript"), err => { - if (err) { - doneEntry() - } else { - getServerInfo(dir, (err, info) => { - if (info) results.push(info) - doneEntry() - }) - } - }) - } else if (entry === ".git" || entry === "bower_components") { - doneEntry() - } else { - walk(path.join(dir, entry), doneEntry) - } - } - }) - } -} - -/** Get info about the tsserver at the prefix */ -function getServerInfo(prefix: string, callback: (err: Error | null, info: Server | null) => any) { - const tsDir = path.join(prefix, "node_modules", "typescript") - - fs.readFile(path.join(tsDir, "package.json"), "utf8", (err, pkg) => { - if (err) return callback(err, null) - - try { - const version = JSON.parse(pkg).version - const tsServerPath = path.join(tsDir, "bin", "tsserver") - - fs.stat(tsServerPath, (err, stat) => { - if (err) return callback(err, null) - - callback(null, { - binPath: tsServerPath, - prefix, - version - }) - }) - } catch (error) { - callback(error, null) - } - }) -} - -function after(count: number, callback: Function) { - let called = 0 - - return function() { - called++ - - if (called >= count) { - callback.apply(this, arguments) - } - } -} diff --git a/lib/main/atom/autoCompleteProvider.ts b/lib/main/atom/autoCompleteProvider.ts index 02c0658b1..b04f8cd08 100644 --- a/lib/main/atom/autoCompleteProvider.ts +++ b/lib/main/atom/autoCompleteProvider.ts @@ -8,7 +8,10 @@ import * as Atom from "atom" import * as fuzzaldrin from "fuzzaldrin" const importPathScopes = ["meta.import", "meta.import-equals", "triple-slash-directive"] -type SuggestionWithDetails = Suggestion & {details?} + +type SuggestionWithDetails = Suggestion & { + details?: protocol.CompletionEntryDetails +} type Options = { getTypescriptBuffer: (filePath: string) => Promise<{ @@ -190,7 +193,7 @@ function getLocationQuery(opts: RequestOptions): FileLocationQuery { 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}) => { + buffer.backwardsScanInRange(/\S/, range, ({matchText, stop}: {matchText: string, stop: () => void}) => { lastChar = matchText stop() }) diff --git a/lib/main/atom/commands/build.ts b/lib/main/atom/commands/build.ts index c812a5cbd..7137990ed 100644 --- a/lib/main/atom/commands/build.ts +++ b/lib/main/atom/commands/build.ts @@ -47,7 +47,7 @@ commands.set("typescript:build", deps => { } }) -function _finally(promise: Promise, callback: (result) => any): Promise { +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 index 5e9801675..0f906fc8b 100644 --- a/lib/main/atom/commands/checkAllFiles.ts +++ b/lib/main/atom/commands/checkAllFiles.ts @@ -22,7 +22,7 @@ commands.set("typescript:check-all-files", deps => { // 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 + let cancelTimeout: any const unregister = client.on("syntaxDiag", evt => { clearTimeout(cancelTimeout) diff --git a/lib/main/atom/commands/registry.ts b/lib/main/atom/commands/registry.ts index ee9771fb4..c5d3f7b50 100644 --- a/lib/main/atom/commands/registry.ts +++ b/lib/main/atom/commands/registry.ts @@ -4,7 +4,7 @@ import {StatusPanel} from "../../atom/components/statusPanel" import {TypescriptBuffer} from "../../typescriptBuffer" export interface Dependencies { - clearErrors() + clearErrors(): void getTypescriptBuffer(filePath: string): Promise<{buffer: TypescriptBuffer, isOpen: boolean}> getClient(filePath: string): Promise renameView: RenameView diff --git a/lib/main/atom/components/tsView.ts b/lib/main/atom/components/tsView.ts index 5043406a2..2cfffc5e3 100644 --- a/lib/main/atom/components/tsView.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/tooltipManager.ts b/lib/main/atom/tooltipManager.ts index ebe7f4165..33bb8a666 100644 --- a/lib/main/atom/tooltipManager.ts +++ b/lib/main/atom/tooltipManager.ts @@ -45,7 +45,7 @@ export function attach(editorView: JQuery, editor: AtomCore.IEditor) { // 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.element.screenPositionForPixelPosition(pixelPt) var bufferPt = editor.bufferPositionForScreenPosition(screenPt) @@ -57,8 +57,8 @@ 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()); @@ -130,7 +130,7 @@ export function attach(editorView: JQuery, editor: AtomCore.IEditor) { } -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; diff --git a/lib/main/atom/utils/ts.ts b/lib/main/atom/utils/ts.ts index 8ab03dff3..01705a10e 100644 --- a/lib/main/atom/utils/ts.ts +++ b/lib/main/atom/utils/ts.ts @@ -25,7 +25,7 @@ export function spanToRange(span: TextSpan): TextBuffer.IRange { return locationsToRange(span.start, span.end) } -export function locationsToRange(start, end): TextBuffer.IRange { +export function locationsToRange(start: LocationQuery, end: LocationQuery): TextBuffer.IRange { return new Range(locationToPoint(start), locationToPoint(end)) } diff --git a/lib/main/atom/views/lineMessageView.ts b/lib/main/atom/views/lineMessageView.ts index 0a1692a1c..dafba2c70 100644 --- a/lib/main/atom/views/lineMessageView.ts +++ b/lib/main/atom/views/lineMessageView.ts @@ -64,11 +64,11 @@ export class LineMessageView extends view.View { } } - goToLine() { + goToLine = () => { this.options.goToLine(this.options.file, this.options.line, this.options.col); } - getSummary() { + getSummary = () => { var pos = this.options.line.toString(); if (this.options.file !== undefined) { pos += ', ' + this.options.file; @@ -76,11 +76,11 @@ export class LineMessageView extends view.View { return { summary: pos + ' ' + this.options.message, rawSummary: true, - handler: function(element) { + handler: (element: HTMLElement) => { $(element) .css('cursor', 'pointer') - .click(this.goToLine.bind(this)); - }.bind(this) + .click(this.goToLine); + } }; } diff --git a/lib/main/atom/views/renameView.ts b/lib/main/atom/views/renameView.ts index 845eeadff..dbc2f33ed 100644 --- a/lib/main/atom/views/renameView.ts +++ b/lib/main/atom/views/renameView.ts @@ -105,7 +105,7 @@ export class RenameView } } -export function attach(): {dispose(), renameView: RenameView} { +export function attach(): {dispose(): void, renameView: RenameView} { const renameView = new RenameView({}); const panel = atom.workspace.addModalPanel({ item: renameView, diff --git a/lib/main/atom/views/typeOverlayView.ts b/lib/main/atom/views/typeOverlayView.ts index db78ce505..332c850c1 100644 --- a/lib/main/atom/views/typeOverlayView.ts +++ b/lib/main/atom/views/typeOverlayView.ts @@ -1,6 +1,6 @@ import escapeHtml = require('escape-html'); -export function create(type, comment) { +export function create(type: string, comment: string) { let overlayHTML = ` ${escapeHtml(type)} `; diff --git a/lib/main/atomts.ts b/lib/main/atomts.ts index 1b18edd8b..99679626f 100644 --- a/lib/main/atomts.ts +++ b/lib/main/atomts.ts @@ -155,7 +155,7 @@ export function consumeLinter(registry: LinterRegistry) { }) } -export function consumeStatusBar(_statusBar) { +export function consumeStatusBar(_statusBar: StatusBar) { statusBar = _statusBar } diff --git a/lib/main/typescriptBuffer.ts b/lib/main/typescriptBuffer.ts index 0dbe972e5..d63498d68 100644 --- a/lib/main/typescriptBuffer.ts +++ b/lib/main/typescriptBuffer.ts @@ -103,7 +103,7 @@ export class TypescriptBuffer { this.events.emit("saved") } - onDidStopChanging = async ({changes}) => { + 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) { return diff --git a/lib/main/typescriptEditorPane.ts b/lib/main/typescriptEditorPane.ts index 162d48e23..1992849eb 100644 --- a/lib/main/typescriptEditorPane.ts +++ b/lib/main/typescriptEditorPane.ts @@ -132,7 +132,7 @@ export class TypescriptEditorPane implements AtomCore.Disposable { }).catch(() => this.clearOccurrenceMarkers()) }, 100) - onDidChangeCursorPosition = ({textChanged}) => { + onDidChangeCursorPosition = ({textChanged}: {textChanged: boolean}) => { if (!this.isTypescript) { return } diff --git a/lib/tsconfig.json b/lib/tsconfig.json index e6ddaca24..7f8ef9953 100644 --- a/lib/tsconfig.json +++ b/lib/tsconfig.json @@ -6,17 +6,13 @@ "lib": ["es6", "dom"], "module": "commonjs", "noLib": false, - "noUnusedLocals": true, "outDir": "../dist", "preserveConstEnums": true, "reactNamespace": "dom", "skipLibCheck": true, "sourceMap": false, - "strictNullChecks": true, + "strict": true, "target": "es6" }, - "atom": { - "formatOnSave": false - }, "compileOnSave": true } diff --git a/package.json b/package.json index c80b6388b..9f2516fbe 100644 --- a/package.json +++ b/package.json @@ -61,15 +61,16 @@ "resolve": "1.1.7", "tsconfig": "^2.2.0", "tslib": "1.2.0", - "typescript": "^2.2.0-dev.20170128", + "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", - "@types/cson": "0.0.30", "cson": "^3.0.2", "mz": "^2.1.0", "plist": "2.0.1", From 714bd9704da65aee86337bc27d7ed367b343b5e4 Mon Sep 17 00:00:00 2001 From: Guntars Asmanis-Graham Date: Sun, 19 Mar 2017 20:19:36 -0400 Subject: [PATCH 69/70] Clean up the docs and revert -beta naming --- CONTRIBUTING.md | 38 +------- README.md | 140 +--------------------------- dist/main/atomts.js | 7 +- docs/CHANGELOG.md | 4 +- docs/dependency-view.md | 31 ------- docs/faq.md | 35 +------ docs/grammar.md | 18 +--- docs/out.md | 104 --------------------- docs/quickfix.md | 54 ----------- docs/screens/build errors.png | Bin 31313 -> 0 bytes docs/screens/build success.png | Bin 24651 -> 0 bytes docs/screens/compile error.png | Bin 11693 -> 0 bytes docs/screens/compile success.png | Bin 11006 -> 0 bytes docs/screens/emit error.png | Bin 15001 -> 0 bytes docs/screens/proj.png | Bin 41657 -> 0 bytes docs/spacepen.md | 9 -- docs/tsconfig.md | 152 ------------------------------- grammars/ts.cson | 2 +- grammars/tsx.cson | 2 +- lib/hyperclickProvider.ts | 30 ------ lib/main/atomts.ts | 7 +- package.json | 15 +-- 22 files changed, 21 insertions(+), 627 deletions(-) delete mode 100644 docs/dependency-view.md delete mode 100644 docs/out.md delete mode 100644 docs/quickfix.md delete mode 100644 docs/screens/build errors.png delete mode 100644 docs/screens/build success.png delete mode 100644 docs/screens/compile error.png delete mode 100644 docs/screens/compile success.png delete mode 100644 docs/screens/emit error.png delete mode 100644 docs/screens/proj.png delete mode 100644 docs/spacepen.md delete mode 100644 docs/tsconfig.md delete mode 100644 lib/hyperclickProvider.ts diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md index bbe065a3b..5ca2fe677 100644 --- a/CONTRIBUTING.md +++ b/CONTRIBUTING.md @@ -57,14 +57,6 @@ 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). - ### 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 @@ -75,24 +67,10 @@ Also [if there is an error in `projectService` it gets logged to the console as #### 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: * 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 f12bc588e..ac8d2361a 100644 --- a/README.md +++ b/README.md @@ -1,13 +1,11 @@ -# Beta - -This is a fork of the `atom-typescript` package with a very different implementation and, necessarily, different user experience. More info here: https://github.com/TypeStrong/atom-typescript/pull/1166 - # Atom TypeScript [![Join the chat at https://gitter.im/TypeStrong/atom-typescript](https://badges.gitter.im/Join%20Chat.svg)](https://gitter.im/TypeStrong/atom-typescript?utm_source=badge&utm_medium=badge&utm_campaign=pr-badge&utm_content=badge) 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 containue to receive minor bugfixes, but I wouldn't count on any new developments. + ## Installation 1. Install [atom](https://atom.io). @@ -34,25 +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 -* 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` / `/// { + 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") { @@ -141,10 +140,6 @@ function provide() { ]; } exports.provide = provide; -function getHyperclickProvider() { - return hyperclickProvider; -} -exports.getHyperclickProvider = getHyperclickProvider; function loadProjectConfig(sourcePath) { return exports.clientResolver.get(sourcePath).then(client => { return client.executeProjectInfo({ needFileNameList: false, file: sourcePath }).then(result => { 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 9d22aadec..6f8dea1f6 100644 --- a/docs/faq.md +++ b/docs/faq.md @@ -6,42 +6,11 @@ For grammar issues go here : https://github.com/Microsoft/TypeScript-TmLanguage/ 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. - -## 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 `/// Y8;}m6L`6YFh=iu}UP4nkgn){O z^cq4(q!U6Y385xu$LD$9@0|CZGw%KKj&Z&Ww`5BS6M?4G4J2*moGejQ1WWaS158GXQdcNwRTp5Qpm zrReq$Xb2SDweY#^>*MU<1u81*x(5`UrWa{Cct7@XdFJEd;SOSF5)=Z;PtnUYJe~!5 zxi~rdfJ)f9lz>v!Kc!v{59w6}d|aRoAbAQK6L5!#e#gYa(Z~OxmjlT58I4|@`A_FA z-jAO?1gd(0YQIz=fZ~(%V)KVy?k?_5pfB7D5kT1=(o8&jy&gM&$h0v0zp80?K%oxq zKA`Qc#AcxE1ih)Li_cRBP~qBu7ziW)0&Ctj4M<&`3<@5?zM#=4UBWYoGst5{&s||p z_*JTPcFFbjsk)l;@A5AF&bP%UyJu~qAyUKECf#Fx@H`0Gwt2*Uu(ZZe{$9%2zG}0~ zv*#j@m~7kueKd`KE^2e_#j!h%P4N4UAHa@Cx%T^_!sUyzR}pMmyQzv9a!E^#i>bYe ziLp6aLB=LOF28SmWOO}1CH+G@%em5;-xC9ay}IT~p@}$5S5kH(R0yi%>Kf3Wsex12?(%oD~=WRF}KObRmxA*QR9-f|5 z#hh2KMto8;R055)5qyxxk8_0k+3AbybEewk_e`08s!Cu*I16_^yO@4qR@QCzT4k#O zQbv?4B}`Xp%DWhg%FPvy=2y4N(TW~;!N91L7S+oIG(UkZJofWh%Ym`6aeRDyZg_aO zb87zh*5maz+d)&q!}$vfj`9i$ZltAt9Wb~*R!IA0kG6;K-wo{;#M2HRc~p+ZBazuT z+K3Yb#KMhdN6*)Ux#98cF?SE!Vt5BXTz&kca`a^kFx#N8G>5su{`8^vt6!CcmL4)u z?gn?ni@UnJn^{|1$0wg6rG5XdDIzSqG>cGA^x5{vp5*{qUHGZwm;e3AN&I_3jVGTi zhK7fSU6$;tYTRqB&5Gq6$(00}b%wLeB9j6oUdAiy*A1wttgVkh0%0%br9%rk$1u2_gfU!lPtAR<16uS9>gkm6Dg zZB*Nxi%U0i^RWv*bIDLjon0nLceV{-ZekMG+!p7c3e3V43vwajH5=K!I?q|3)sfHd z9kM59=bqgp{owXk+RC6cZp_Nb$&u;5#;2)%6G1&AS{~eZzGa{vw~0E>Q|H#a>HKo~ z2_{{$jdFanlb=>j+mrp%E55Y$y4!F`=wIO@T1{l83EI3Y+){n#E1S=3v_i-1 z#^tM5jizZ-iZAVu;x_j)_Ae})v}B~0d|iCC9w7Vq*Gz5I_q@$F*#IsnEiHA0Ldm@` zt_{^zrAjbTAuuQzLkuy1Q@1k61?q=j|LKt0vW682%=VaDvO2s;SX@rdBrh+oVFgue zYHq&hfhbSkm~F#Xbjl23C{x9Gx=DNdL_c&joEAFiGpHvaEsY&CP%jlr54gh`p&{qk z)mP!rNg8u2-wjH<vp08hD`w@nnF$@QDJm`18yy`TYw#^zLlf2J7Z>+Cot&KT zzrKduhI*qXVH>TS^BV#51uPFG7gO8(pOzD;k?dkaBO`_T#AbV(t-mc|tha{tltCi{ zpb;SbGC29_Zf4mrOFN9A6i(&QY z!3+1MUB~(P`CU$5HgmP1!)N2W+G! zCU#LkW@q8-_gc~nkN_hlq^Flrrh*K-7rK~M^iDyVieVJOc){41m9%}6O*8F~nDFsq zQSB5=H{}L&V0o~B3_Nayd2bk$HllOt6aor`!bttv5KBw(cJ50_QkDa=dw4uv{^7S{ z$5+t|Bkue)%h8 z@O#1ASdp1vpF1HNEa&+|Tn2K%)JX3~^2Lr1E8?04bU40ua_9DX?#9;6sK*djIZw)^%<48Pwcw@PJ)Ohci%hz*6wZSt?pj+_y zeLMVq6LwEo6kJP%z#PkKyOKn~oT=k-)eN9Mu;KI7 zoq2`z&|l4igM&dTae3|1S5&-ahX+$~`MO!3!jyqI92gu#9|j${azzSl!SyJPy0+5b zwDA!$u&*tW0%?#gCXR8&?B7pGZ-Rex^(VvwUv*B=5L~Q$C#{G5Rn|QL`6j)Nh8Fk= zXoN7aPAE8bT>$oAsDSt zxipracHPh^ySA9&L)(UD@jgwqI{bcqAKX0ZdaITxul<)s9uk#)GJ(NXdtq(yN}gUx zh)U5BA3P$1gnKAKAOA%!DX0XP%V|!}loV;BgDq2zOW4 z0YGOsRKsZTb=!Yk_z*sl+pi&v(1x|`2gQbuHny1CH}ojKk`Eaf-NcfOQ?x6@bhdMs zs)YmvjqLX+Vx-CGc>Iq9b)&m3pT~MqBd3@^nHeqzq)#`fYfLmk&Ln!y6I~s0Sm~XyN(WbmtgAH{nZ4LOx@gQ5Afwbax{F>Wrdb2}fLJwkr-DvhwFLLVR= zO4YEiuy85+JuPVF1Tk29r}&>uGlBNAy%h~d@a4S9%|Z^jIJ>rG722{`m)h8)>?hI- z=vOmz>enZ&CxdU*N8L^$>U-lVZb z+hx^D_Or}Lqm9gjaS=bD9!IFHReEpx^C1>j&kR2k9PpPC7YE-+(UX>zrpnIur^{CY zq8qSz)++rgcmu4b7jJTq=@y|M+BPyWQYmE5$MC`ND_2row|W|s{66?BUvQb;DC=}8 z0N;q3b4{=*cs!WjfFZhU-pxpm78K0RDth5s$gt)BSyqEKoi3v5@bhk~dl-Y8- z>!TT@*|-dDNuJ&#X%tXN7FkpWEL_rM>C>B)BOrD@gf>5Rb$}!r3So+jv`z9wlYcZg z`40HrH?w}}C{+h;&oL1OM{E=O(blx=?}8dWSaT1^okx!hcfo@)Cc|CD8tJs9EQHVP zp2g|{uP9NwXP--$YCfposNYEY#T#daNhBX$MK57TRmB%LQ@Sk{7KGpT2ka?lXG0iF zNfq%0gq;w@!0%UB<;wbpv}Xw~hi~N`D<-{=RKlt6r78}hoI;;Pgn9<0Pr*ZSWH5VC zs%4!a`FappmGV&q&Yy|D4pn!*rS`g!MwkRU#e{|TI%86h;`<-2*T)QL+pvK?-1Oai z)l-$$zdpBCP+1n@R3K_kvh1cUD#v>h%&W>*@i(8m2}f|{2t}y9-Sbv47r8f3| zu8~^KzG|Fey$99v8DB!5xaRx&3GZ05d2tmE3v&T%@x7EF4 zK2%Lq^W|S1{y+jFbBCDXAd4kNW4T*%aoC0;IT?4gZtbJB*xEcyeeLEZ(?{Z z+He{%gtdPj9N5~=E4RHopBpIFv%7|Oa(c+?7?++(V2MML2DB&Hd=eOV3}n40!S)t7yZ!_~$PYmCM8ho^YUeS=uC<-g`LJ9Q0=r`Qio9C(0{D5^j7 zJ5ENcm=ARF$!9CyDG|jnb8@oU{%ia_EBUoXX5ZDmHXXjSOXe*FT-T%&otNAi zX7BJS?qpf%*Ij=!bU_3G-b!L?#jY0_tI1iK_jFN+-c7c7k0aPNH9npMkOa-SkC>_P z$L6pI)QK@8BJUWNWRsgfUM2pPC=0oa9~q*Tt^@a}rCM!D+G0q4Ic{g1fDH$i3B3=9 z9Rp-M1s>X${)H z>Br6Q9G%@Yw<$t#W|-^ECuX+$26L^jUiN*o{tPmG#q4PAlZ%S3Rc($Azu7=ve)*Ba zHZH!T8tU8VbDKnKuaMg^rpn>4B~I#dX3+jL%5>qp-0bALx|QDYud-$G+!Cn*;Kelm zHQO^|fO|v~1)PZYIUDX@Kr;X*?u`}rPB|#P(gxj($So+~PI!D$5(HXG=pg5fZ5N!S z9rpHE|7zwt3%c^@jKC4lt@5r$s$+K}bs<0jP_B$68}5KD1p@t=xN_xau9(UBH9Sdy z;&Z+gEq$n;)q#?P@II5Az55nnX>i$p@`f#D%`)#t5z}3V1k`0at_A0YbgO2=l;Opd zbmxqK?Oh4`Wlo*N}umCPHN$S?ZoK05XR+9jrLII=K9*=82Gii3Wqr$#Y zdVh92oLabKtT<etKWu zjL`4N_&R6Bz&mCs(o@|_)qrE+^6U(E@6dF8#h0dTH%7}hBS{F}eGUe$JoIy_fDWGsc^Y zzNYORm85fgCLB~ti>~u?#;(r)_6H!wmn@YC;~!4mzb8+Vj5XtyRLDa_a+h5150rFl zEe-#nI>njbWwh-|ec&L>VH zonolxEPlilz1_y2m-SGm8A$7S1(Y$%h=Fy6Pfzcb$gX(dfnM5^XWC7ha?f@qZXYVo z#VcIdTWOrwdo(xm**O|sk(yBN2foJZVk zi-`2Q-`SdA8tfVDjTE@bRIUN&!V%X8UEjt^pG2ERpOO;uF+|of zUO6C}-ByiEJRFm1@8{de{YzpS;9g^DP|^RA7)i73;B?O6Cm$MHK@S_}r7Np3e9)1M^|qcoFTTeh>THxkC>L zVpb*G10Jwc4s&U~?$9LboScZSPd;IeoB6cPt0>Z5t(~$QdJKTXhXk13Bjqk%3C-fJ6Q~P9%&nxL{!uRqq^elRZfRN zuOIq_0+|ujTTnP6f{Jb4y4QEO5K)fhpsf$2B;3Ht5a0?A>WYLDR_4TzKlGf5GeL&S z9|zi1t(DlW5`_8#`3M!p4oRl)Pedm>vO&5DyW=JgJ3;k>p0+X#bLfK;6c4OWQ&)cJ zg)#K{bQ@_~^bo!)K9HTs?*eF(6MTsqOIascHyge;J?4`7&3-F;`OavZh=^<-7SHkO z<{Dup%G~)nE^cwgSVPagsx*u)U^QUNSyQx9p531%tb<;v#)AS$*B+Ux|L%cxh)~W1 zQH~!0U3j3M;d3!b=Bo8@U$qv+r3~4jO&7*oxUn#@O*Xnq+Yym+Il!w=R<5jzDu~6 z<;s<>dS?42Wit_NetBRrl1FeQIudCPsg%;LFEUZ)?a-;#E#oENJU=GN&GUX6qv-f< z#wj0asI*Y7*DzM~bDkiO?ffsNt*%|K6irQo%8TC5&_-|DRT`>;NF%FTkkH<{I>Uk( zpAg8>^Q9COr^m85zml7|A=6FwMjs=wS1+Wii(0zE?8_ndkS_J0z zMvr9PqK+CG!piL*G%oJ#u!1f~0hpwz{q(HMdB%6Qy;+_ZoUdPW4rg_-{UUtxc%lZ< z%XCH&ebTjQ(RDHt5cbP1#E%{?Go;S@C%4OUq?>$QuxkHoc)nHlFlZ}EL85oY7#r7w zue;w#hO@v&isIS_W=3{ zjjh-ge4ZtTy}&EqP!BGh3VE6$V_B~kldxGf9-xuNgXcIF(NgNaG`TD5rZsiLHcbp% z4Wop&$v4jRWRkBbGxjYfe|EPn*wWe$3{WlTmY+6tU*kEyC@Fz?1Rn{wRl5)nBrwf< z@ywvFXZ}!C4rkorF^RGPm3h}e7Vl~ojEB>kDFa~t#5P-b^CF8^u zO7c0?J-;QJ*3c@t->0VL*`pB>d<_vaHgnjhEC+58j#xyF0(D%4a8fTT1r z`W^z%72h-8Z_TkhZ3#NN^Sdm>InO(+f|LC9TiWsZF`uw(_KCg7>k*h@uOE(49zy10^9Exl-eHxTHJA|MRe z0ID82#H=>$m+@N32h~5SG0o^L5sOEAHH7c40cs^>*S}D4c#$Owuz$U|`LL^>m_Ko% zN?=($M}ku4<<^G#d3a$>r=}m$Bpj5QXp@Pej1+iIn&wM$W*jfw3Ilf;|eSdhn z-K)DNy=ZmyqlEwVOkgdb%(=^k5`hc7zrWtddoBS&->}^a?%#5NB^G`qn-Ln555dU;>=7cDVplzOr19(GNdp>ov7Guoe*!S;DMRw}ckG;JU*kP)zMg%L|Lo)tDoAuWUr zB*GKM^uZj(*Eg6q+-9#3CzU zm@(FzFl#XNu3SZK@xERSKD}e~z@g06IDGSHnEe9_xsbG=&Cq|_gK9h+wkv59ZE6s2 z@cS=c{M)a&%pIRWAa>rxhZuC}69GTB*#6*7t+ZXqIEU;oZ*8cCba#mI;YaDO`LvyR z_{xA}MUYKI8)3LpwlNdUA7JROzLRalCuv;%*>1q(Kn2s&gu|R3d4vPRfjPd9tLvv%qbK%4te|Rs{Fh zYQe2c9vY7|id`=Wnf|oP>00MHPfC)+zQ8K`8vBh_Dye-`?5NN!3s=oDu&xunJO?f^ zP0asSElp%gtSMQNL{viiL@d*g`r3*u@=5M4N4On(A85$SBity>h zZ+gemo~iovEpW9xjW=_$P`f@a1zs) z266SAMD6ykC%}Grey6{N-nBY+&h^M?ix-`KJ|Zr;{+5W#L0KjDX#tbI$v}v5my-8R zZ?H;Nc4Jx=9$MP$f9;ubVR@S?uBX<=>GlhE>qZM=BZR=OwSwj^d-}k@$sA+kBF8%^r$WOY!S=gQgxa>r1%pC zCOez3%k>{>D#eIV%Zd#6b=9P2y+Z50%&=}MB~OOpPu`;}U?R8oPYJ+ajjVI>xGod- zH6I{OcsMW1oii%>*s{nE%%bHG#B2KUoQu&m-+A*ALwCD8)Ru629tx7?bT)b_us{MU z)81r=#WHK~7(hmX*^i5A#katOhXNIp?o>O|U%l3j8tHphRNrj=y}5wQnAG`QIoZ3ajfQY9R& zsSfw5KFc2WvO`o@)OFv@n*6;NUPcV1?N?ZQqfr~FZ1ABsb59Qa2v)qiRd%$kA&=_S z9_6s`!m+bY_xc|rma~G)TzB7|Prm7bRB^BM!$1fgL2cWlxnN#<1fd*?6^metC@mK2 z4IKJ#b#FJW`4mhhwrcRvXDw3GhxAGU5Ubh4mRIdjnsI#(TV8Jai>%96jy@f;HW{3! zmf6v!8WsA3?T=`hBVYpFUS)mf&240A$4jf-XoZLSZaEWDa`G%PvlX{B495eVD62(_ zrdP%la=pS*D>uEG{4b511XvbqVTW2Bivq#wqg&hYUr2x$@Z4dAmB=aO;RAt{fG z_0*fN0-9N2;;iU`Kem|jBEY@cL~X!DFglF}^%(Ic5#B2qWV8RQEzyqWQHPm!+uGnq z{POj0G?Zlss5Y_vb9cX`$E$pHbt|49|t~Ais zS5zWAAG)T)tL&BADZ2u78Y3;#;0}FbzWNq@6!!=<$sUG4REwiZHe zb3}=h%@}R6O4}5jwlx!et!E%oj&ih&@iI}ik3uH6CfO)wKby3Q<#5n-z%q|Bba-FA zN%U5-X#S>die1Vg#EqRcFP&oH{@w7|H;Pp@L#AzsS(%qhZA?ahv* zGBCaj1m?wyzS6okU%w%3u)};qi?P{TJRc_$-Jq&Dz-AtVtGoO>V_Ul!NjsbqZ!|Fgp1Y@sATk=`ao`o4f}d4#yPrUF6G{$;`ygk6l#kDl^uY9A5A#; z9o^wwXIhP7#Fd^eHER8?enRiZ@3db(@=)DPA^qzA!j~jFPeC4iBE9xE<_32d?h%YN zmUM+1j8F_IO_#K%j?Pn`mBTNkJyZ|2OnTBVXX6`@Jl>ghFsCoRbvDo(x~j$bRrXqb zxp(h0!kq!WpR0qkt&d{PJ8Kqw>;%tr1uw6!{40nOx6$gpx6d;*SR#4h01#+&J9f=Do!VL_Mi#a}b8T|IBcw4B8Y38<-VC zfRu}23?;M|zF!MRYp{#HLqL>U)>(z5{b3P^y`+G;)inLe3dbZ|M>_h_1D7`^5}YWX zY5@>4eMli}_^i#x;vS4a_#%K1FR7<58txlkn%Y1A0?(ExgUKj6ZU9Ya?L#4!gqKAPR<8HA$PO#q9j)i|`JZTT~+@ivww88J| z(Zd66#IaI_fVn{!A#~Ap^z74Q&v^)JyQtuReX-HdET6eRkGbJQkEt8}B6M#n<#Tt4VRy&`Lpv_daf-8hmAcmqxSDJEhTyLUX9TnE zMO7$MF29!H?%oP#Z%`G4Vl*JuE&T4GJ66!Esss=B{zRFeEBr&Pc#g}ZE(KFv6tWI1 zPpw8TX%17;F8}pKW$rJCbeY`ZyQhQZMd#%J$*=}h=2nXq|J7>+{oS5?#n(>#*vXs z$-z^B4bY9>Z&s{6ImhzV;mh<9c-J&-aL3Os(~8M8kA3Oso$!8NsBIc?kGmN~qa`(y z`1jW^6u&=HwaUDH7f1zi3N_&wQnP-k$Lw){;;Y-z@1|`g9ma8dtg0+#ifkB|R1A@u z`O7vNUc82MJc;O6CUU~4-ATRXe+n%9uCLB5dC6yc49uC8ul z%JW+UoVDxX>}~vAovHMmi-QD|Y_l=Z_hi;?D|huZ9AD$MBiyJ;3mbUx1k|nh#6Y!1 zu|)^NO(%@~&}?LTkl13@PHHW4lOV#jTjCS|`pa0YXBySpl`=5xKuZU~;Fbcr(qCWo z*gCFGDv#fa`!l@IyCI$?yR^g~@ww=x*`zBW30q7Pc};+pD9+SsD>52U~JESRi<{msw2MEvIH{qZB z;^Vwu0|{UsM0{NdaEfGaU%TKP4G0=;b z3Shhf<;_$j%ThB8b+5*`ijiL2XK?p=WDF73b_+;F#Tvl(oK3lp|EUkZbn3kuF0mEG zOaJ*iv<# zFnY}gw=N1CsZdo>Qn(ysWYoz0hj0dC1j7?oSCl)NfY-TqukQr|e{t^IC?8htbG>C; zN=n!^FQ1ZWbxTBwx$)nQK0$y9k&`hTVxKOK&SjgfyJw)J%;`Djj#H533G~x8$qU6$ z&5ob8GIPhV3PoI@yKa9ci{}fO|M#f3cDX3*Sq)f7ovJK@$TLN*?=)Z zWAW%DfBZQN*ml;Pz%RrUQG#WM)(owP>xn>V9X7w@Zu_P-_@}C0{aT$~wI_-nky?xA`cG7gF zN2l-BZ{zYGRc{7upQF!eYRe_o_dr@n#{R^8`5Sz=;nHzf@bCW8(#gb&gJTkbDp_nC zr5lWm|HO4phrSRLgI7zSI3-F~j2xVLP5rj-m!iDdV{w8!$%#>M(kU_n2B=V66qlB3 z*M~CQo5q8}*y1&dH(_^^U}EAG23VW3^eud4NmJznIm*6KtG!)_bg%_q-L+KZi@vf{ zf8X6L4uVu3`U)r$_l$?~fAF~*g(^XjN(K!LrmdY`Pw3+0t2Y%Ra(pWRVph~xUz|`r zFL71oPoTv6y3pzdJ$MK|Mke>n#R`eYuPpV;oQe*$(v{^A$4!Y{n=%_ch3o!n3yEQdZz!qYfFtyOdey)mfACNq|kGy(ZOZInKG;S`M{t-ohKGO zH*cmHz96?wRjXR@$S&zFBUwF6UE0!HpECst2a5GGjdxn+-W@&6l%%IN-?9Nf9r^}K zQ=3EqJDajr!V$F+hg9lr8Z*)`MoyfFTl!F_zGFjqed)4)&w6iFgS{-Yp?PcLaqWuO z5%wh|I`h;v0*PAY^koZ6@_gR7kQ~UR;GSv+4@m(;9eM9NStH!}pvXkWCxRzaqP8`= zMI)TFr=sS@Xn=*_oKe(vjIig9W~~P2z;x6@%;4 zE-GFB-S90)|9DC>3V`cSm#1<@3G8!ooF1m>Er9#l6zO@tGmQbp!eEOW#v3U*-g23%+*T9 z?f@s3E4Iaj+_d}KwDdfB_jK|`=|CS&ZgJW788fc?eG|Yj> z`_^v&W6mZ8(^o9jL`q0Idb_KUpaM2Nw9k=ysAuo&;u7i4enNzZ6!)t~@sTM5bn(q# z`(JvY@(23J&7^a#o@EqRpBU4hT++-z+3-)>-+vC9*#;lf2``7uJqa0`X=oROLY10} zz(Us68hk{;EMpP?|5;?&poJGtILQ7U(+0YJa7D=};*(5y*>Ka`leC&qpN);#F-6CB zQ}=WSi?;W@S^0-uQuLxDBe}*0vKd+;@bgUU2W`z3=D685x){7*bK%>HZ_kN)y^-wH zD+)DvcX7j5mx&@1WUh%>@stj@zvenIH47kt+}fa|rxa+69QyE~(COMW7-^?1Uk^XH zNY~c_)RXV+7N0&pEg#u4lE}dVKxX~xGlKkb71a=+Z3~}5VDRHdk9xUTfXcs8HJ_7| zoXTIE&O_tRakI0dPd^t$&?V*buWv2?);j;GO=6Fn6JUmz*%qxlw;s*3DC^sAlzf|{ zl~%8{76wnE%=PrZrEsj6vbq`BNPx^8*pmO}txz3D@77_qx5AaiR zcdxIKSw$ei27n)>@SL&|^wDp=apoAN<53e6%W2!_Nq1G+0sp+uu-3%$$nNgsi3y%6 z;(A{eils7M>)zd@4nZJMg!QdV+sI|B9F>SUsf_ZM$TMyKbApDEI@2PZq&?&BodI=| ze1Iyx0iE1~l^cWtY1ul;zNkSe379VzHxoUtiYLpV(2j%1A|#j371Q+>FYYAFJKXDG zv1M%eCL+-cWTphVnVQyVKA~Gq51vJiE4?o&Fo-yfP|LBlmR}nZ4;knld$%waQGa69 zGckf|!PTnF?QhdE)K7cu6vVuIecBhIiW)tBMC0z(pOC;&zP}b4bs;vN@4SHMB8yEJ z?&IS&qZWT=StZD>G%?mbBd~Vce$1(F)y;d^qhUL)8)&bAV=Ya_*v!G`R6KYyF8>}F z9xW}GUk%v|xWg}HHJc&T#yxZ`p7Um;{;yZEyTuSAjG+qzu~&|;fy^U?%3Cy*^XE^; zpX>4{e;k&&dE&<=j>L`ue5T2WEdUUY3+|W$#f$h{@*u`NnuobEv z2zl?uSRx*^dqMqlwo4Re#D>HhhPb~FOyrX+{Q-)e9})Tuask{Pw_!*FWs0~A$hU%^ zHA}$=A)yK#6~5@3-udH?+M&=HZVLeH)y zm{MBX9rt&zwLqWXb6FA_x~-%-==B1KOl3D1W3g`MLcc8V$-gSX6^ESV23U;X#gWoS z4sbFgfI|qbTyw@tzj*X1FB%LTunDL#R(TgTV9e*mZHH^u zd@M(f?WVF01MWH#d;S=LQD0|Jjk_dAqrO|dEED!83T76TT9!V9D~ke18o5P?qoeY| zXfMu6t3Q^Ip{5VZ-0#*XpRdOk83{p@NlI1dVHCzy6R-=ojE!Ls?W9vlm#y7Q(>Uum z9+!4hCLNQteP~r?+rFS`m6#%gcC9XsN;RzmPQU=cmx+V~l-=?qXC3R4#aSSx4l}i? zx${Cu7YGqZ76U?|$qSHj=@{+S^O9o>)^%I2%X;yO(6ZfpFK^7(s!a4n*rvIgyMNs7 zKVewrkAFmLYVrS3eZ2>4QMzk*do-#cUA3B?6Bo0dHP+_O>-fNseo(Rp;^N{0oIgVN z%l(#dk6X%A7ate{;tv*u6=j=``?=;7g`EO%Ge#0azio)VA12E!=}O|4O@Fb2%9*ME zMb9buIQMP*&x#H~o>kstLv)W9{!ZRai>O%m$7{{J`*3j9n2u?e*-p(=Pm&zzs`X~= zl~?jwYhxJeePo>PnB!n8aAs=p!&R7&v|hm&u~#wJq5yhBUR2cescsbOY5uY#vHR=% zv`4nK_xWj4g+_u_1eWKP@@Wxi3!EN99Yf|!uYq1K!~N zp}f!kd-B~IAAjCQj~``op)F|FhW}QQWmlL1Py2u4GykV&CQO>U9Vccm+#5<|1|peY z0ugo%0~RP-M&h{XRF<4;DugDfv^rzPMh6qbPkSLcAzX$O%s{yP5iICDAf zy!m}xaXA%&P~Wb!sQ%-h_p#meVR_=W?UQ!X^A7io_%;;%q#NKjcGNLmla|)Ic#$>j z=FGt6y#Hmntzg>K@Jf1@U%qf|NR_aQ25T|0^7LhwOAP^+spm#{e1g25`rZbOGiv*f z)49hq3sM9QPet=68vFY4GuqO2zJ-(b_NU$Cp<~zeGSb=O=m)BRn0oKcTQ?LGia&q8 zI`>&fJ4UngHof>cwf*L;VH~db^G4mkV4MGn%Y87|$YhX7zQM-GLx5f-6aHq2>!)6d zU2L1sWL-cc-2V30W(j~;40%|eFpd^mVWHcTAQIbOr3|~k=*Zl0cS*z1j2rimKnzbu zHv{Y4o2c3BORw}iR45xH9;lHkd+!ffClGIvHt07%r}h6|fDWVp*f)Y}b~5ITgA+}o z5r{?upRiN^A7PUJTylC60Py)w^XdPDvix`R|22Q&zo(AQJ^v33=Rd)@|7M&2YuHA4 zO71P--~D+n0G%}+{0pG{zlaBZ(W?CyH;k|pYTI;Wn(+ICW5@?5V?&q(rLqm7lX>nC zcM5p+_J}C+38!bV^7zGtml8!&wu~@?|Go_yZ_(tf#*Eu zxiJmZlXRlKthXuugZkTnm548+o{ZPn$Z&#@!vFmHalc%+I%A24BTVq$g%O?$Ko48J zN{ljvH?By!A#SHnO*HZs3R-BMCz2*AT&GO%Ey>1prHfQ#wt9pF>bm8=WRSX{7 zvqCqOtv5B7p-{`BXQC1K?Wgx9CkICOndJ8LyO=>5rG!uIZERtCj@E;dL6O8x&)fJM6J?+$~U(d(g zL3-lgG_BrH(n!=91#ba84DNKC8m%ey`-{@)=`qUKHj~^V|Mp=oSlXzFM8+rZ9XkWrNXzTh=Q* zqydjH?rxWzaX?yJSzWn5LM;G(O*e11h2rJQ9+k)_(QH)7m5W1@ge2&=Qb=$@=z;pQ zNumQ7$;uO8&5sEMTMaAPE_>Bi&Fvvv=TY)n`;q@JMnupyiR7vqf^l{1=|iLkqsp7! zmzvwta-NQI#m42#%a**?l?mD3SNBb)wZJl`zoGzdTS!)Ls_`R?j(Y$el=ara&{Cec z9d?t`Y>5yS;WNe9J3I^>#}X)QP=zxmoylY5m9@1S&Tx8@K@U65bc!Hh6m5^Dta+C; z@BT1wC8kd{tp9FJwl&Ea8yn>^H_F0I2M9^y(_*Sb+7n%!%-v=eYQuw7{+ZE_F%ua7 z46Sz;vRXN9Go`I-70F-LF#A=QhY{ZD8S{g@wG+9(OuFn6?YIop6%`dFBzc9v5`6L< zyB)=>X zgVfCFrgh`4z}GSgwLC`FLFh)cjJ3M?6PSZB?y;tjh(^0|Z^fZ$$#P6q8k({Vg>NRj zTK80_1(NGu_9gMvTGtC{qvn6czQOa`?G+yVnhC(@S#^QRy2=6*y1L}Ny>CrSuB+xysRweR+Z;$+PqD5pjtNgIfZdt zR{$f^)2>*0yi@I7hIiJ$x{FGU{LB)S(C9cm#6K&u>;4nq>@eZwnv|r=u>=-np_R8U zwoR-}(uVz71|`8?<2aG&o37)?OU%NLYbKld$5|(H9|&ZI>{E(SUa3@4Qi6nx%)odA zD>+0cwlgpL+a1-tZlbfkUN!Kh3dOOyWocdy4_rc$U3N8IVX54sY#50z9~^3rtAYlF zO^r3^)lN2QN}6L8TOADt=+$ycOJOTc>Pgb=o4a#f^+WyrSp^w~)6IuGks)5T`rC&i z3e7pA@>nI>lj-UG8H8_Jslv*<`E*|mf#q;v-mBhc^mmjmaGgJWf~=09<$5&L@b-r` zcZ%VJ_Vy%YF`57yV>hQUbMJ(Fnhl#}YOMkIVrZO^Td0h(C$%e_5FfwvZL8Nr;7s3E zbCBR8xM_9ma!)j#M7UU4Rr={3rOdXpld?Lr(w~RSbrQQjfS)fYLSag$=am)8yk&Yl z)JhDXlO+*Oy}k=uU9Z4<8oMsZ_Eruh%r*car{4-W#$#C?U?5hx~1X%r&72uvym9tZiR3J?+O6tf5(jQtpN0nPHa|6+f;lg$T`x z?aO28h;_v_@r#(++ugOo`K<}TK}FS7Hq+Ob*F$wxp*NDV+djHx%r`Oy65WrQ4m?jP zuml~TaI&be?(_`SqQ~aw2Bd3-VdyLe&D#6(M&B7-u@Hm5&+|MZQ6imxw%3-@vll}! zM{qb|eeV8~ik&x`n4o{s5UWVaUD7{FC2R=%8i)?H3u%zBc=e{m`0DoYk=i#~6qC#@ z$1kr|xbl5bhWiNf)6=8OUbSwdF?q9LCAPt=P+(bUi zuXn5#-wJmUW63eTI&4Fi-YSzq1*9((K_DyGBSUMtVXf2Bf42HBxt6J_cj3ZzE{I(4#OrW@VTv{x5WZkSX=7=KFA{2Ku{~TJP@8BEuP4kEY^8-CMz*pZ4e*$2BEL5 zot&I1)l`SI?wc9%{1f&|fDT)0xWNJ1;c`kJG6TQ=;N)jPgf=&{7@S(${@%PUFd!rJ zmC4zkc$tK6@d?LO4+Y}W`f2&;XU@>)cfJ(gW!z3yEbRT<%~0hf-awXO+yMm7fZkgMYYdV9v$|cJao2EfH9$wA959L`l){vVwn_EE z44I$oasM%Tg&FdI%LuESIghnynD72rly%Cw$!+aiGr>hYsjM!rLUgNQ%;8Cty=6|d zZW69{G7n~kJ=~*HyO@FVU3QQAqPy|#nP&a-^!w#$3f!foB9`%^&uwjigwl?B(k+^r zs4Smqgtiwh#$_ca5Px*HH7u`fO&3&nd6uDdeTw|(*5z@WX=ui>Q9;K`CTEX@if`14 z`ix{sak&G9mZXDx++U`tY+@(N!O$uA(y-$l4G0sWLhDR0JHnRI+-L^qM;z5;_qI1eNs;LVR^3ND%j3eHdy+^=|BrMPkS z8??^n^hFvMIAHsL+gjj+lxs<|w0IP5U*0 zaKaEpE)Aa?b*KUEb557~Jn`lvwU+tnKsh15ls;wU)D+zs=e8iGeOi_#zqTkbz9KHm zfuKvYhtWAtOjM!DUZ2R)nJ75?6nt!#0dG<3!;OD}w3uqOwqu8zghp}2M52ddY?}fj z-ja0QJCU+BQ@+@aYWh-+;X}coaSc2hKU`5^8mGbc=?(^wtsl`R#ur}1onm9II5^az zB3=($+)SS|r^}_Hx5gvO+;Tqq9}w${JCssfaUelO8aCu68|I&^ld@Wbr<_Amn zTWz#Q^8TA1EqM`g_+J7?!8B+6yX?dZK8?oThW)b*1xe`n&AAWX(X;<~X=K*I0ev>x z0R2Aqy5^z(QnNplvhM!#CIxJ_=ogNIMh%}R^!jHrtwX7P57hfl|MP-ri$%GDEW$@r z&h*nyF`nUc*5+IT_<({UdbbE3sAJs-R;nd4PtMO~wImBpBs zBO2152%cZ67 zr$j4{i*fes3R>>6tetJ{?zGdzRaL4-JYux*-@ZME%r3o)T|yP{<)^}SCu!zVBM^p@ zCz8qI5k3Z5nn@Ei9TZC6^PEy(^lZJnSbxy>Zb6JA!2#JCcs!&bzvW&#k=$Kpo(IRC z6d>PUndb`{mPvf-VA)NlA{iaaw#;y6b|3QDO(&n3BQ_^%l)7H^9nG-pl^N77h5h=yGw$4ux4n9`#8lkU0Ytp1LDK2U&J``zFfB7Oec;q@$|f*;Z*g6y zZ95`|ukne}_uZ*Cex&3qAu83|ykab2szR*6@X#(_Dh!q$^-C&jGP!F2>^rbjEs057 z`raXr$A&obvBcZ*l+x0!GJ}ZTf$;X%Si#mo+C+T(W7aWyek<+Np2_7k}sKdvZzw=(!$9K*(etZc(#nZ@R}LQ-WL^naoG+G zQX-KE0S+6)k1C%iR9r?QYa0H78>`dexFz7W0)+N~e8|~|ju)4c&#tLKz%D%4JWvx+ zu4MT-zHKys*0G2TY&)qGp1DbeZ@-@(FsDV149Jf&a2M3QkzurkPvJ$Rg zg*{$|f@RQ2t{TNuPBJ)9)iI8qGb{MgC?rL^Oi0L!-nv&ZPPMvYZPV68hH!<13Tss^ za{wf(#(U`8ctA(V6q>ayMbD!lF>-k2@m#pRT-4k`7F#DSlr82<4^;1SiApehwhnk|52mnW*e;ze#n`bpZ}q#NU9thnFu#$?%! zk9!A2bJ5k+H9X*}O~cq!v8|JyB~ws7v&?2CFokX!gu35ue7|tvf%8f~=IAfmn!h|>)W`X|6pU_9tr{aIj{QUc5m8W9J^{8-|V9Y1e0+?&jy$ z%*j^1IroI(eZZrwrpOP``~n-wy3^@ld1sj-TF_lI@kuZ1$w z2`rVK{y@jAd$mD_ugG|9y>@Bz8}}T zIj?{yWtMezmenons1ZvwF*U7FYfB1bD#EBX^|+x|^qEPH9iTh1&|nv*uTH)O!RGs6re4xu~BQ7_u?I1cHP|4kL#M-@rcJwRh zNp02##ngyPB`ggZT4o!#Y_2QEguOEaZTj@!@g6$|x9rtbeeLi4*`O2f)B_2J*WqKk z0QGT@m6Z(-oy>_}$$ZI-pfFTaRC;2>XPObheCZ@_SQIhSW$C48m=_xb-0aq51hV!C z=BzN?Pm(a@6wGwiDUX&whVX5)m{pwvVU_>5Egz+-q5>|Xsi<4HRE=$Q0n;d5uO@sp zyS%W5n~chsOf{wu@xj4OybDOo=x9R1v{0Lr584jyc_k$!xokOS zCJR9ZEog;jY8l~GZWz{X(0Nw6VRTIT2u&}1Hy#kXD#r68Sys9;q41R-;%$L51|h{I z)wZayo++k~CGAfp&3D*|c?fACB-O&1z#&JL%=hqzGt@JOpUtih&$SabfDKxxKiF0Y ziX~>LcK6QG!!FbkbIuzW5G^AVKjxf5eD*x9zpx9dq7wV#$WboQnMtQhFCSQYcZpWp z69T#YqqvJBEBk!r+34tGb4*BVrg1;Mw6jbdAU~f|xNBd4NAlQSi=8&=awZQHZ;0wRdU#DPgb9lSPvQ0jb1$Y*6+yU9B!RP)X) zF$3E=a`HwWuL9`D?+moC>V+tE(`ZUnstwqnZFlty+|(2Q2=aEY&(-d$|T8UMgP z|NJ#W6Nv*6wt{QK3+^dd)-@c~ILf%({T1toi<3_ws)4Yb=f^rL6nsGO(MdP}WC zLPFlpIVR>6&9Q=pHcL!AFE`4q?7o_il#n0f7c(Y?l&04Iym3QNb;v}EbYgRcJ0aM7 zOb#B=R(UFDYQLg5ytASuZAvE5NZ9ze=2G=E&@$3G2-;v2zlTcA0U`u=n=D{3t2*as zhpijun&Fh0WjLdO+pzF7%i;X_Xq(uSSOe?ENk_^=6y#ahrkMlBh?^uK37n2zc)HDl zlZvZarz&ji(}U;Vxr+G{C!y%*NxJd%>vx@TGMWv@iHx}T_#2}0yMVjbsymE;4`6`j z^ldDd??3eY+pvG5>yCl5*iWtgZpnux2sb#;7up7PY;PySUR#GYHn&;7w5E|>e&!G4 zZMis@t7}Y_%jLojy%(?I;zHwcreC1K3#x3o3t{}ba?&YRuj+s1-OwzYG41tRCRK9^ zfMT#Dpw97lVUl6*G73dj7Y`WEi1l z_Z9@;1%14B+sCHTN}NXuz%EzdzNPgH%wK z+2<5>V0_-wCvPsp* zNMp!FTvpgsS*eDV(Y%U4a5_OV#k&?XJ&{HJ)O<}SYqo?a9pY;;z!1dA8%rYFDDqfOkAxrW0fH){qrj`H!%t#U#Jf51rD1I zh1h~qRCTc3!Dll0G4(MHkM~_FnR=`|xCs#0>IjM(_P9o$)6Ow=Y#1um3L_#e?UPhs zhECE#ChW#4yEQ@Nzlt{cH9jkgIb%y8@|VDHhZI<37?Q5S*tI5+t>pJwlq-k7up^f` z19!iw#r9%Oc&n9++QF@4Czx|}|( z!8#CLOx!^|1wY9i8U0*pv5I&ZF~-=#{B))x`{m~fxu>mj*0#2p;}@$AQwLM$v@%!thbmO0b)Tbp0euI z3=p2G0klOGyZjyO!|v}J|tShXDo zlQTNy!?l#MvvtPgbA%J*_ zE*%5Cmqj_;%1|n(;s+qn|9TRj7YDRm-nQH zaIQ=}{8iK0LubZ*MBd8s(;scxl;V@~WXGe`S|(oSd!*HpQO|;uy2rNdQLar2<6ir& zM*Rj&9~0lVk`jGyb#+6B&(YmvuFPxmcE!aiaXMayz7_V4VL$a3Wa|`Gu9;qa~9ID^IS9QPY<5Q^M z1H92nmb^gsh3h&BIH{1cdF0iFoe4lPG?Eq%5EnY3Dc?ows{Hiqx}?E_pxa^f0|Ns` zQt5_c}_X74N_uj6Y(p1RJCx(Ja=m>X- zxM5}3Otm_aw-Enw_O$3*f3Gk3emjTHi@c>=aBE~g%_~z-pBc6^-Y`87=ezpjvO(pd z<~Y6(ENp;-8s^H|Oo*n=_E(5UXy1z{$);E{^krFC;@KbF1{Kf#m%5D`^RVpD2rO3_bhWNk#Sr!s_ zbm;H5COp^Z+8)D|ykrU)Pp=AM)W|0&06=9hH*#{ky4SdNy(Y6gk8c)u()llf^3bwj z=OshX-3k1iIJe z+{WXj8-)Gym1qysQ)}-IIryi7<~JVrtU^NzzLiO%(n%tIGC*a?iFF^$3EpPNKBM|5*u zneDTMK_k9!_IS$dHN4a0&wQb5(d{LiG1}!#w_Vva#<8lNVO~T0_?5wY6L!i=I8R!$< zPz?NdTfvm1RyCTXv^o0S%a)reuJD(W81eY+TcVwpdZ^A#=xC9oVH*W!EKM_tK>&On zqP|NWIML<75aE@*o8I!%l~tkqwePp9n8DQu7&YILHWDLl>p$QK#$QcHpf^aDRaREo z+Cy6E)kR@6PR5{UaL}!n*4`}=r%j55;bV)Bm(GpRXx@>dx;Jk+X$m(SKc;R^Z^g%N zm-isYh)+#T;SQPoIApPcBUvG>%3JJWv2{pm>*rv8_kzE2!9>upW5?_*xaJ@tE&}TK zHXR4WksJu9Kh}rJh}Hk#^Dv zgvCIhry3$IHwk_*d^o}SFDP0~7uh?| z9jNP50VCVMNqU`|>o|Hd4-#IjJxx08L@|bY%rAc&nM-^fH^DUvj=WE!;SqM}_GKVE zC@u+%#XXdj&&T9cRaJp3q!xLW2Ox+jZxgfwlWsgS?umJk!+%n9F=ol`RnyMGRsMcK z-FAi?(nyIl7rL0eH!}y69uxv_ZDH|fSJ0SI|SP(Y)kRz7?* ztvDTVj^iHsj`z8U#NOi26a%nDuD!3|mThBwu0XBdsiSmH*P ztQbXLaTM4@XTK&*M6udJ7(U;uDm|3L`4dqxGd~=g zuIEe(#>;a9WghNi_QkXuXgFSda40EG4iSW7v&#ff;Ekr*wIn81;xO%#T8qi3dY4UT z0^vvZ4gpUCqa7Z*X=aOD+*c>vV;RM)fO^}es7Ll?MWUcvN~^&b)T96z02YX;J$-wi zB>GXiI}uz+Eu|N5U-Tvz3_l4*Sm)$5>Li_7vv+6!gNXLJs((TasVHb}UtcN&C*ufgmReIuxo(atWqte&KL z!w>B9m;U*HnwnZT2e_$E8h2WN1^Y|X9+AHAc9yC6w-bEfTw|YsYM-- zeXT2x-I|QaCUqrhW<=tK@y*fq?yc6bMt<#W@XtgCfn zzDgH*Pm=fauNAl^N521I^``GvxjzI`(@SlfV0I|o-(dF7^Hbly_gLttci~sUMG9jw zsc8*cMp!*LIx>hq6#0&}~hlH12-~h$$l@L(sxr<{!aF0f-1pi3m8Yyw7m& zc39)NS!C+#-B8QcTjh4>fN`d1y1h0=*$viJd!gK}g!@L#Oayb@JtE~dk|IOeCBD7t zs|z1%PX@z(d@gjQ)S^VsIBrxF9M6xms;D0C715^Q)|+B<<2df@(5)P_d0fV9*vA2K z3@+}j%%eF4X@^%FT&-;1GD*0pBVF^nXpJY);{==}>$Xup*{p=TaTfh-{*l-MP^pv} z04Pe-;BPawM&lRa{6JzpJUl#O>GBg3pMjUHpteg=%Fg!C+}?Zpi?2y$;3?Y_*{~_7 z>}i6d-^|40qsE}pC~&wLdeQ3eZMr?MwwC2Zr=(0yco%c~EAE34ndM#T!LgwRe@Ky& z2JSC?t~Mm_)A+(MC^Wzih}ZClh+YQccvF+fyK7&3kZ({svA@!u$^vQ`SXZw%Ts>io zxIfm_9bk;cSiO((YRE6}l@<2^t0>)c0wP6Bkh_wM)e#Lkw2O(^y3CDT)`i@eeb$+* zWAZ2s7GFke4Nt}SpCDg+W%z2HJC>DH_td+?*_z`IqCEu{YURDA%!-Y;LilqYLT!YgY|>ILtM35nb_q8saVn6(2@>rcJKVbod~7#Ki$`g4JUI`+#p zU3vk3ZX>}xcTw^a;hT#c0MTj1eV_1%@%>rm+l0HYF@Q;Y{`~nQ2?OEd^4`38tA|xf zxuWR;5-?h09bF*%vVYeWY>OBYMqOiZsJ3*21ab=ieQ|Wo)h~N|K?%=-I`_=@0XQ?I zWU|oNq;0-1zrh*QOo9xMVDQ4s^pff?6Vhp97EaefI}<2d(=M_Jfo#3psz*f49~iNz zS=wZ9`ea^isBN>P4A7d541PC0tD#WY8IdJ^oH^W+?0Ku8NYo zO_$PeOCg-W(#%Y`48h$C^E^-!$@Kfi1TrKD)OJi}@~1_~BajWrc#hbjLJPmt{lQGW zSHx*eNNdkT>4<_6t=Drc-Tgfw4G0tp)r2@VLwgv<1vvDiA??m4J;ULSpt{yYmRP8c z8BcMjY+4?b|CBf^&W5r_}PZKkyYRA&st&w|VRF7aLx@k=C1FeS@K zWB63>Y{h-%L1daS>uI0;tD4Jrxu&%aWbe1`8;h0>mnx$?Adh|lQO?lEB=5-_VHt>3 zJ{lmXfhC({-771|5X0^$nHF{&r-JOk$_M691vgpG1Ycjg zp8I!Th$1J-Yi6ZZOUHk%s6YxgcyaQr(uQL{8bd%LQV6E4dstYM#x@1tBauRdhU1az z8JZegg>fyD(OasSWA+UV&U8KcX$a}bnTd+Lz3?F?FG#IOw+{n%3xd|g{_aQIbw*^Y zW9zBLYvwjwZ&g;{5_j5bqa(YiORs86i(xsMIVQ{4(RQs2iLe~iG3kVw#`JtA`J_XrI;=@dtsW9afuWEKrcjI!0xA zydh`DoH_i5(Hf7^Fne!jY+RCe!Hx8{5zj@H{pv@}S3QRqxdAQ@1_tO_0YxthkG)VX zx=t=TYmg$36YS*@hOyZofjuQHb#lqG!}u>~L`y_)kCjsHI8sAzbojic4OBC;T_}O& z7Wp_XFr^l05Z=pl%XA+AkF@sxop}ZM)3)kNxzLVY2Oy?)9gq5M^rQQiMe(Re&nexX zpM@D_eJzl-;?117HSqe?`(K5eT2SE1d?DI}hi!+>0h+As^L{dZ#qHy_MOxy^tWSFi zc=zw4$No5MggJwfy8OZ4V5^EaDg`F;N1$HyLnA5l5ckfkUM=vmUAt# z&Ux}M{HTaP%#xBSHg>b-Kv$Y++Gvt{V&Px)Ck0>Lp#M6g6Oo}>T@yilXxs606kfq+ zPEi65ZmQtYf*9o_pN`a;m3A+~Qb1t!mN9dA2b@W(VWv?9rRWuE$R{>O+WGJ=cczoP zp`xvwxm7>Ea|h?%xhl$`;E*6mo$qs@fy)jgz$0}O)aLWS?$MFLmusBtM?GEs=iDPE z&Jveaq`_D69@BAh2yCP4;yMBP>6j{%K7j^5bi`8;(Mv&f>cK>aYdm1WwMC2K@<(T< zC2?g6ehjgGjmsy3joTUL#5~pVIu|4K>h@BnDq5JbrVV|a*mNK9aDOGf?dQPi8aq&E zZtQ{yw@Uzv+M;;xpQ=CWqlfVBP_K)k3~GVZ3$Tb|P2XAu3igU4I;5Xc##=vkl8m5G z@(gYEl`B4{slJwW5eWM!|l>~T}q17`lb$JMd;J^%!=C6-`2BcUz{eIPV5w&0@DkY#%1TO-TPm_3!B*h diff --git a/docs/screens/build success.png b/docs/screens/build success.png deleted file mode 100644 index dc8920d504cf3a1dfa393d906a5cbd802d30e479..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 24651 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 diff --git a/docs/screens/compile error.png b/docs/screens/compile error.png deleted file mode 100644 index d66a2df551d2f5663a52c7a0a3050844f0aec45e..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 11693 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 R1>C>{DJ!VUmp!u#`7g&Rx<>#2 diff --git a/docs/screens/proj.png b/docs/screens/proj.png deleted file mode 100644 index 77ee955bc410c3859543706be120b3f93b6c9663..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 41657 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 diff --git a/docs/spacepen.md b/docs/spacepen.md deleted file mode 100644 index e6fa9de95..000000000 --- a/docs/spacepen.md +++ /dev/null @@ -1,9 +0,0 @@ -## Docs -Official docs : https://github.com/atom/space-pen / http://atom.github.io/space-pen/ - -## Gotchas - -* The `outlet` option does not work on root. `this` is the root jq element -* `initialize` is called after the view is attached to the DOM. The body of the `constructor` executes *after* `initialize` gets called (due to `super()`) so you cannot do `public something` as an argument to constructor. Our workaround is to have an `init` function called from the base view *after* the call to space-pen's `super`. So `init` is where we have the dom available in the clients. -* Tip: You generally want views to be singletons and *not* take options. So don't have an `init` function. -* You need to add the class `native-key-bindings` to your *custom* views for input elements backspace to work and text selection / copy paste to work. diff --git a/docs/tsconfig.md b/docs/tsconfig.md deleted file mode 100644 index 2a0816460..000000000 --- a/docs/tsconfig.md +++ /dev/null @@ -1,152 +0,0 @@ -# `tsconfig.json` -A unified project format for TypeScript ([see merged PR on Microsoft/TypeScript](https://github.com/Microsoft/TypeScript/pull/1692)). The TypeScript compiler (`1.5` and above) only cares about `compilerOptions` and `files`. TypeScript `1.6` introduced the `exclude` property. We add additional features to this [with the typescript team's approval to extend the file as long as we don't conflict](https://github.com/Microsoft/TypeScript/issues/1955). - -`tsconfig.json` is great for building the ["compilation context" so you **don't need to use** `/// { - // 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/main/atomts.ts b/lib/main/atomts.ts index 99679626f..d84d3d962 100644 --- a/lib/main/atomts.ts +++ b/lib/main/atomts.ts @@ -1,6 +1,5 @@ import * as Atom from "atom" import * as atomConfig from './atom/atomConfig' -import * as hyperclickProvider from "../hyperclickProvider" import * as tsconfig from "tsconfig/dist/tsconfig" import {attach as attachRenameView} from './atom/views/renameView' import {AutocompleteProvider} from './atom/autoCompleteProvider' @@ -31,7 +30,7 @@ let statusBar: StatusBar interface PackageState {} export function activate(state: PackageState) { - require('atom-package-deps').install('atom-typescript-beta', true).then(() => { + require('atom-package-deps').install('atom-typescript', true).then(() => { let statusPriority = 100 for (const panel of statusBar.getRightTiles()) { @@ -166,10 +165,6 @@ export function provide() { ] } -export function getHyperclickProvider() { - return hyperclickProvider; -} - export function loadProjectConfig(sourcePath: string): Promise { return clientResolver.get(sourcePath).then(client => { return client.executeProjectInfo({needFileNameList: false, file: sourcePath}).then(result => { diff --git a/package.json b/package.json index 9f2516fbe..ef47b4e8e 100644 --- a/package.json +++ b/package.json @@ -1,11 +1,11 @@ { - "name": "atom-typescript-beta", + "name": "atom-typescript", "version": "11.0.1", "main": "./dist/main/atomts", "preferGlobal": true, "description": "The only TypeScript plugin you will ever need.", "activationHooks": [ - "atom-typescript-beta:grammar-used" + "atom-typescript:grammar-used" ], "scripts": { "build": "tsc -p ./lib", @@ -33,21 +33,16 @@ "versions": { "2.0.0": "provide" } - }, - "hyperclick.provider": { - "versions": { - "0.0.0": "getHyperclickProvider" - } } }, - "homepage": "https://github.com/TypeStrong/atom-typescript/pull/1166", + "homepage": "https://github.com/TypeStrong/atom-typescript", "repository": { "type": "git", - "url": "https://github.com/guncha/atom-typescript.git" + "url": "https://github.com/TypeStrong/atom-typescript.git" }, "license": "MIT", "bugs": { - "url": "https://github.com/TypeStrong/atom-typescript/pull/1166" + "url": "https://github.com/TypeStrong/atom-typescript/issues" }, "dependencies": { "atom-package-deps": "4.4.1", From cc813065d8e277709fd32780be293f439e87546b Mon Sep 17 00:00:00 2001 From: Guntars Asmanis-Graham Date: Sun, 19 Mar 2017 20:34:46 -0400 Subject: [PATCH 70/70] Remove some more unused files --- dist/hyperclickProvider.js | 29 ------ dist/main/atom/atomConfig.js | 40 -------- dist/main/atom/gotoHistory.js | 83 ---------------- dist/main/atom/views/lineMessageView.js | 64 ------------- dist/main/atom/views/plainMessageView.js | 22 ----- .../atom/views/simpleOverlaySelectionView.js | 69 -------------- dist/main/atom/views/typeOverlayView.js | 21 ----- dist/main/atomts.js | 2 - lib/main/atom/atomConfig.ts | 40 -------- lib/main/atom/gotoHistory.ts | 92 ------------------ lib/main/atom/views/lineMessageView.ts | 87 ----------------- lib/main/atom/views/plainMessageView.ts | 29 ------ lib/main/atom/views/renameView.ts | 3 +- .../atom/views/simpleOverlaySelectionView.ts | 94 ------------------- lib/main/atom/views/typeOverlayView.ts | 20 ---- lib/main/atom/views/view.ts | 4 +- lib/main/atomts.ts | 2 - lib/typescript/readme.md | 3 - 18 files changed, 2 insertions(+), 702 deletions(-) delete mode 100644 dist/hyperclickProvider.js delete mode 100644 dist/main/atom/atomConfig.js delete mode 100644 dist/main/atom/gotoHistory.js delete mode 100644 dist/main/atom/views/lineMessageView.js delete mode 100644 dist/main/atom/views/plainMessageView.js delete mode 100644 dist/main/atom/views/simpleOverlaySelectionView.js delete mode 100644 dist/main/atom/views/typeOverlayView.js delete mode 100644 lib/main/atom/atomConfig.ts delete mode 100644 lib/main/atom/gotoHistory.ts delete mode 100644 lib/main/atom/views/lineMessageView.ts delete mode 100644 lib/main/atom/views/plainMessageView.ts delete mode 100644 lib/main/atom/views/simpleOverlaySelectionView.ts delete mode 100644 lib/main/atom/views/typeOverlayView.ts delete mode 100644 lib/typescript/readme.md diff --git a/dist/hyperclickProvider.js b/dist/hyperclickProvider.js deleted file mode 100644 index cd03a33d7..000000000 --- a/dist/hyperclickProvider.js +++ /dev/null @@ -1,29 +0,0 @@ -"use strict"; -Object.defineProperty(exports, "__esModule", { value: true }); -const TS_GRAMMARS = new 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() { - // 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 - // }); - // } - // }); - } - }; -} -exports.getSuggestionForWord = getSuggestionForWord; diff --git a/dist/main/atom/atomConfig.js b/dist/main/atom/atomConfig.js deleted file mode 100644 index 48ffaa5c9..000000000 --- a/dist/main/atom/atomConfig.js +++ /dev/null @@ -1,40 +0,0 @@ -"use strict"; -const utils_1 = require("../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) { - return atom.config.get(packageName + '.' + utils_1.getName(nameLambda)); -} -function setConfig(nameLambda, value) { - return atom.config.set(packageName + '.' + utils_1.getName(nameLambda), value); -} -class Config { - constructor() { - this.schema = { - 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 preferredQuoteCharacter() { return getConfig(() => this.schema.preferredQuoteCharacter); } - get typescriptServices() { return getConfig(() => this.schema.typescriptServices); } - get showSemanticView() { return getConfig(() => this.schema.showSemanticView); } - set showSemanticView(value) { setConfig(() => this.schema.showSemanticView, value); } -} -var config = new Config(); -module.exports = config; diff --git a/dist/main/atom/gotoHistory.js b/dist/main/atom/gotoHistory.js deleted file mode 100644 index 66e061d6f..000000000 --- a/dist/main/atom/gotoHistory.js +++ /dev/null @@ -1,83 +0,0 @@ -"use strict"; -Object.defineProperty(exports, "__esModule", { value: true }); -exports.errorsInOpenFiles = { members: [] }; -exports.buildOutput = { members: [] }; -exports.referencesOutput = { members: [] }; -/** This *must* always be set */ -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, line, col }; -} -exports.gotoLine = gotoLine; -/** - * 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() { - // Early exit if no members - if (!exports.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 (!exports.activeList.lastPosition) - return 0; - var lastPosition = exports.activeList.lastPosition; - var index = indexOf(exports.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 */ -function gotoNext() { - var currentIndex = findCurrentIndexInList(); - if (currentIndex == -1) - return; - var nextIndex = currentIndex + 1; - // If next is == length then loop to zero - 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 next is == -1 then loop to length - 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; -/** - * Utility Return index of element in an array - */ -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/views/lineMessageView.js b/dist/main/atom/views/lineMessageView.js deleted file mode 100644 index ebd328a78..000000000 --- a/dist/main/atom/views/lineMessageView.js +++ /dev/null @@ -1,64 +0,0 @@ -"use strict"; -Object.defineProperty(exports, "__esModule", { value: true }); -const view = require("./view"); -var $ = view.$; -class LineMessageView extends view.View { - constructor() { - super(...arguments); - this.goToLine = () => { - this.options.goToLine(this.options.file, this.options.line, this.options.col); - }; - this.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: (element) => { - $(element) - .css('cursor', 'pointer') - .click(this.goToLine); - } - }; - }; - } - 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(); - } - } -} -exports.LineMessageView = LineMessageView; diff --git a/dist/main/atom/views/plainMessageView.js b/dist/main/atom/views/plainMessageView.js deleted file mode 100644 index f59c8deff..000000000 --- a/dist/main/atom/views/plainMessageView.js +++ /dev/null @@ -1,22 +0,0 @@ -"use strict"; -Object.defineProperty(exports, "__esModule", { value: true }); -const view = require("./view"); -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 - }; - } -} -exports.PlainMessageView = PlainMessageView; diff --git a/dist/main/atom/views/simpleOverlaySelectionView.js b/dist/main/atom/views/simpleOverlaySelectionView.js deleted file mode 100644 index 53a3cf403..000000000 --- a/dist/main/atom/views/simpleOverlaySelectionView.js +++ /dev/null @@ -1,69 +0,0 @@ -/** - * A functional form of the SelectListView - * Only one of these bad boys is allowed on the screen at one time - */ -"use strict"; -Object.defineProperty(exports, "__esModule", { value: true }); -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; -} -exports.default = default_1; -/** - * Various Utility section - */ -const sp = require("atom-space-pen-views"); -class SimpleOverlaySelectListView extends sp.SelectListView { - constructor(options, editor) { - super(); - this.options = options; - this.editor = editor; - this.$.addClass('atomts-overlay'); - this.filterEditorView.model.placeholderText = 'Filter list'; - } - get $() { - return this; - } - setItems() { - super.setItems(this.options.items); - } - /** override */ - viewForItem(item) { - return `
  • - ${this.options.viewForItem(item)} -
  • `; - } - /** override */ - confirmed(item) { - 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(); - } -} -exports.SimpleOverlaySelectListView = SimpleOverlaySelectListView; diff --git a/dist/main/atom/views/typeOverlayView.js b/dist/main/atom/views/typeOverlayView.js deleted file mode 100644 index 839699602..000000000 --- a/dist/main/atom/views/typeOverlayView.js +++ /dev/null @@ -1,21 +0,0 @@ -"use strict"; -Object.defineProperty(exports, "__esModule", { value: true }); -const escapeHtml = require("escape-html"); -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; -} -exports.create = create; diff --git a/dist/main/atomts.js b/dist/main/atomts.js index 7df056b24..1cda79fcb 100644 --- a/dist/main/atomts.js +++ b/dist/main/atomts.js @@ -2,7 +2,6 @@ Object.defineProperty(exports, "__esModule", { value: true }); const tslib_1 = require("tslib"); const Atom = require("atom"); -const atomConfig = require("./atom/atomConfig"); const tsconfig = require("tsconfig/dist/tsconfig"); const renameView_1 = require("./atom/views/renameView"); const autoCompleteProvider_1 = require("./atom/autoCompleteProvider"); @@ -17,7 +16,6 @@ const typescriptBuffer_1 = require("./typescriptBuffer"); // globals const subscriptions = new atom_1.CompositeDisposable(); exports.clientResolver = new clientResolver_1.ClientResolver(); -exports.config = atomConfig.schema; const panes = []; // Register all custom components require("./atom/components"); diff --git a/lib/main/atom/atomConfig.ts b/lib/main/atom/atomConfig.ts deleted file mode 100644 index 692e8b0c4..000000000 --- a/lib/main/atom/atomConfig.ts +++ /dev/null @@ -1,40 +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 as any).set(packageName + '.' + getName(nameLambda), value); -} - -class Config { - schema = { - 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 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/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/views/lineMessageView.ts b/lib/main/atom/views/lineMessageView.ts deleted file mode 100644 index dafba2c70..000000000 --- a/lib/main/atom/views/lineMessageView.ts +++ /dev/null @@ -1,87 +0,0 @@ -import view = require('./view'); -var $ = view.$; - -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: (element: HTMLElement) => { - $(element) - .css('cursor', 'pointer') - .click(this.goToLine); - } - }; - } - -} diff --git a/lib/main/atom/views/plainMessageView.ts b/lib/main/atom/views/plainMessageView.ts deleted file mode 100644 index 8bcf7879a..000000000 --- a/lib/main/atom/views/plainMessageView.ts +++ /dev/null @@ -1,29 +0,0 @@ -import view = require('./view'); - -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/renameView.ts b/lib/main/atom/views/renameView.ts index dbc2f33ed..623a36343 100644 --- a/lib/main/atom/views/renameView.ts +++ b/lib/main/atom/views/renameView.ts @@ -16,8 +16,7 @@ interface RenameViewOptions { onValidate: (newValue: string) => string; } -export class RenameView - extends view.View { +export class RenameView extends view.View { private newNameEditor: EditorViewzz; private validationMessage: JQuery; diff --git a/lib/main/atom/views/simpleOverlaySelectionView.ts b/lib/main/atom/views/simpleOverlaySelectionView.ts deleted file mode 100644 index c78503639..000000000 --- a/lib/main/atom/views/simpleOverlaySelectionView.ts +++ /dev/null @@ -1,94 +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'); - -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/typeOverlayView.ts b/lib/main/atom/views/typeOverlayView.ts deleted file mode 100644 index 332c850c1..000000000 --- a/lib/main/atom/views/typeOverlayView.ts +++ /dev/null @@ -1,20 +0,0 @@ -import escapeHtml = require('escape-html'); - -export function create(type: string, comment: string) { - 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 d84d3d962..8afb9e328 100644 --- a/lib/main/atomts.ts +++ b/lib/main/atomts.ts @@ -1,5 +1,4 @@ import * as Atom from "atom" -import * as atomConfig from './atom/atomConfig' import * as tsconfig from "tsconfig/dist/tsconfig" import {attach as attachRenameView} from './atom/views/renameView' import {AutocompleteProvider} from './atom/autoCompleteProvider' @@ -17,7 +16,6 @@ import {TypescriptBuffer} from "./typescriptBuffer" // globals const subscriptions = new CompositeDisposable() export const clientResolver = new ClientResolver() -export const config = atomConfig.schema const panes: TypescriptEditorPane[] = [] // Register all custom components 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