[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
[nongnu] elpa/typescript-mode 1cea84486f 064/222: Merge pull request #35
From: |
ELPA Syncer |
Subject: |
[nongnu] elpa/typescript-mode 1cea84486f 064/222: Merge pull request #35 from lddubeau/feature/indent-return-annotations |
Date: |
Sun, 6 Feb 2022 16:59:16 -0500 (EST) |
branch: elpa/typescript-mode
commit 1cea84486f937946a90caacf2a7c86ca855d1c9d
Merge: 9ad892fb22 d155a4b623
Author: Louis-Dominique Dubeau <ldd@lddubeau.com>
Commit: GitHub <noreply@github.com>
Merge pull request #35 from lddubeau/feature/indent-return-annotations
This fixes the indentation of functions that have return value annotations.
The number of cases in the test suite makes the change look broader than it
really was. Fixing how return value annotations were handled had the potential
to impact many other cases. This is why the suite is so large.
---
test-files/indentation-reference-document.ts | 215 +++++++++++++++++++++++++++
typescript-mode.el | 113 +++++++++++++-
2 files changed, 327 insertions(+), 1 deletion(-)
diff --git a/test-files/indentation-reference-document.ts
b/test-files/indentation-reference-document.ts
index da1dd7d80c..d6e3124f0f 100644
--- a/test-files/indentation-reference-document.ts
+++ b/test-files/indentation-reference-document.ts
@@ -50,6 +50,8 @@ namespace ts.server {
pid: number;
}
+ export type SomeType = string | number;
+
class Logger implements ts.server.Logger {
private firstInGroup = true;
@@ -237,3 +239,216 @@ namespace ts.server {
/def/);
}
}
+
+// Tests for return value annotations.
+
+// Unannotated.
+function moo(x: any,
+ f: string) {
+ return null;
+}
+
+// Parens around return type.
+function foo(x: any,
+ f: string): ((a: number) => void) {
+ return null;
+}
+
+class Moo {}
+
+// Type guard.
+function foo2(x: any,
+ f: string): x is Moo {
+ return x.something === 1;
+}
+
+// Usage of generic in return type.
+function foo3(a: number,
+ b: number): Array<Array<(a: number) => void>> {
+ return [];
+}
+
+// Curly brackets in return type.
+function bar(a: number,
+ b: number): { z(): string } {
+ return {
+ z() { return "a"; }
+ };
+}
+
+// The sequence ): in the return type.
+function bif(a: number,
+ b: number): "abc):d" {
+ return "abc):d";
+}
+
+// Comment where the return type would appear.
+function gogo(a: number,
+ b: number) /* foo */ {
+}
+
+// Function call in the list of arguments.
+function foo5(x: any,
+ f: string = bif(1, 2)): ((a: number) => void) {
+ return null;
+}
+
+// Dotted name in return type.
+function foo6(x: any,
+ f: number): ts.server.SomeType {
+ return "string";
+}
+
+// First parameter has function signature.
+function foo7(x: (a: string, b: string) => Array<number>,
+ b: number): void {
+}
+
+// Second parameter has function signature.
+function foo7b(a: string,
+ x: (a: number, b: number) => Array<number>): void {
+}
+
+function foo8(): void {
+ // Arrow function in first parameter.
+ foo7((a: string): Array<number> => {
+ return [1];
+ },
+ 1);
+
+ // Arrow function in first parameter, line break in parameters.
+ foo7((a: string,
+ b: string): Array<number> => {
+ return [1];
+ },
+ 1);
+
+ // Arrow function in second parameter.
+ foo7b("1",
+ (a: number, b: number): Array<number> => {
+ return [1];
+ });
+
+ // Arrow function in second parameter, line break in parameters.
+ foo7b("1",
+ (a: number,
+ b: number): Array<number> => {
+ return [1];
+ });
+}
+
+// Arrow function assignment, line break in parameters.
+const foo9 = (a: string,
+ b: string): Array<number> => {
+ return [1];
+}
+
+// Arrow function assignment.
+const foo10 = (a: string, b: string): Array<number> => {
+ return [1];
+}
+
+// Arrow function assignment, parenthesized.
+const foo11 = ((a: string, b: string): Array<number> => {
+ return [1];
+});
+
+function foo12(): void {
+ // Function in first parameter.
+ foo7(function (a: string): Array<number> {
+ return [1];
+ },
+ 1);
+
+ // Function in first parameter, line break in parameters.
+ foo7(function (a: string,
+ b: string): Array<number> {
+ return [1];
+ },
+ 1);
+
+ // Arrow function in second parameter.
+ foo7b("1",
+ function (a: number, b: number): Array<number> {
+ return [1];
+ });
+
+ // Arrow function in second parameter, line break in parameters.
+ foo7b("1",
+ function (a: number,
+ b: number): Array<number> {
+ return [1];
+ });
+
+ // Same cases as above but named.
+
+ // Function in first parameter.
+ foo7(function _mip(a: string): Array<number> {
+ return [1];
+ },
+ 1);
+
+ // Function in first parameter, line break in parameters.
+ foo7(function _mip(a: string,
+ b: string): Array<number> {
+ return [1];
+ },
+ 1);
+
+ // Arrow function in second parameter.
+ foo7b("1",
+ function _mip(a: number, b: number): Array<number> {
+ return [1];
+ });
+
+ // Arrow function in second parameter, line break in parameters.
+ foo7b("1",
+ function _mip(a: number,
+ b: number): Array<number> {
+ return [1];
+ });
+
+ // Same cases as above but generators.
+
+ // Function in first parameter.
+ foo7(function *(a: string): Array<number> {
+ return [1];
+ },
+ 1);
+
+ // Function in first parameter, line break in parameters.
+ foo7(function *(a: string,
+ b: string): Array<number> {
+ return [1];
+ },
+ 1);
+
+ // Arrow function in second parameter.
+ foo7b("1",
+ function *(a: number, b: number): Array<number> {
+ return [1];
+ });
+
+ // Arrow function in second parameter, line break in parameters.
+ foo7b("1",
+ function *(a: number,
+ b: number): Array<number> {
+ return [1];
+ });
+
+ // Check that JavaScript objects are still handled right. Whether
+ // in the 1st or subsequent position of a call.
+ function smurf(a: {}, b: {}) {}
+ smurf({
+ a: {},
+ },
+ {
+ a: {},
+ });
+
+ smurf({
+ a: {},
+ }, {
+ a: {},
+ });
+}
diff --git a/typescript-mode.el b/typescript-mode.el
index 8baad489d3..4b091fa64d 100644
--- a/typescript-mode.el
+++ b/typescript-mode.el
@@ -1759,6 +1759,110 @@ nil."
(list (cons 'c typescript-comment-lineup-func))))
(c-get-syntactic-indentation (list (cons symbol anchor)))))
+(defun typescript--backward-over-generic-parameter-list ()
+ "Search backward for the start of a generic's parameter list and move to it.
+
+This is a utility function for
+`typescript--backward-to-parameter-list'.
+
+This function must be called with the point placed on the final >
+of the generic's parameter list. It will scan backwards to find
+the start. If successful, it will move the point to the start of
+the list. If not, it does not move the point.
+
+Returns nil on failure, or the position to which the point was
+moved on success."
+ (when (eq (char-after) ?>)
+ (let ((depth 1))
+ (loop named search-loop
+ while (> depth 0)
+ do (progn
+ (unless (re-search-backward "[<>]" nil t)
+ (cl-return-from search-loop nil))
+ (cond
+ ((looking-at ">")
+ (unless (eq (char-before) ?=)
+ (setq depth (1+ depth))))
+ ((looking-at "<") (setq depth (1- depth)))))
+ finally return (point)))))
+
+(defun typescript--backward-to-parameter-list ()
+ "Search backward for the end of a parameter list and move to it.
+
+This is a utility function for `typescript--proper-indentation'.
+
+This function must be called with the point placed before an
+opening curly brace. It will try to skip over the type
+annotation that would mark the return value of a function and
+move to the end of the parameter list. If it is unsuccessful, it
+does not move the point. \"Unsuccessful\" here also means that
+the position at which we started did not in fact mark the
+beginning of a function. The curly brace belonged to some other
+syntactic construct than a function.
+
+Returns nil on failure, or the position to which the point was
+moved on success."
+ (let ((location
+ (or
+ ;; This handles the case of a function with return type annotation.
+ (save-excursion
+ (loop named search-loop
+ do (progn
+ (if (eq (char-before) ?>)
+ (if (looking-back "=>" (- (point) 2))
+ ;; Move back over the arrow of an arrow
function.
+ (backward-char 2)
+ ;; Otherwise, we are looking at the end of the
parameters
+ ;; list of a generic. We need to move back over
the list.
+ (backward-char)
+
(typescript--backward-over-generic-parameter-list))
+ ;; General case: we just move back over the current
sexp.
+ (condition-case nil
+ (backward-sexp)
+ (scan-error nil)))
+ (typescript--backward-syntactic-ws)
+ (let ((before (char-before)))
+ ;; Check whether we are at "):".
+ (when (and (eq before ?\:)
+ (progn
+ (backward-char)
+ (skip-syntax-backward " ")
+ (eq (char-before) ?\))))
+ ;; Success! This the end of the parameter list.
+ (cl-return-from search-loop (point)))
+ ;; All the following cases are constructs that are
allowed to
+ ;; appear between the opening brace of a function and
the
+ ;; end of a parameter list.
+ (unless
+ (or
+ ;; End of a generic.
+ (eq before ?>)
+ ;; Union of types
+ (eq before ?|)
+ ;; Dotted names
+ (eq before ?.)
+ ;; Typeguard (eg. foo is SomeClass)
+ (looking-back "is" (- (point) 2))
+ ;; This is also dealing with dotted names. This
may come
+ ;; into play if a jump back moves over an entire
dotted
+ ;; name at once.
+ ;;
+ ;; The earlier test for dotted names comes into
play if the
+ ;; logic moves over one part of a dotted name at
a time (which
+ ;; is what `backward-sexp` normally does).
+ (looking-back typescript--dotted-name-re nil)
+ )
+ ;; We did not encounter a valid construct, so
+ ;; the search is unsuccessful.
+ (cl-return-from search-loop nil))))))
+ ;; This handles the case of a function without return type
annotation.
+ (progn
+ (typescript--backward-syntactic-ws)
+ (when (eq (char-before) ?\))
+ (point))))))
+ (when location
+ (goto-char location))))
+
(defun typescript--proper-indentation (parse-status)
"Return the proper indentation for the current line."
(save-excursion
@@ -1777,7 +1881,14 @@ nil."
(if (looking-at "[({[]\\s-*\\(/[/*]\\|$\\)")
(progn
(skip-syntax-backward " ")
- (when (eq (char-before) ?\)) (backward-list))
+ (when (or (typescript--backward-to-parameter-list)
+ (eq (char-before) ?\)))
+ (backward-list))
+ ;; If the parameter list is preceded by (, take the
+ ;; start of the parameter list as our reference.
+ ;; This allows handling functions in parameter
+ ;; lists. Otherwise, we want to go back to the
+ ;; start of function declaration.
(back-to-indentation)
(cond (same-indent-p
(current-column))
- [nongnu] elpa/typescript-mode de1a696c3c 174/222: Ignore errors from backward-list, (continued)
- [nongnu] elpa/typescript-mode de1a696c3c 174/222: Ignore errors from backward-list, ELPA Syncer, 2022/02/06
- [nongnu] elpa/typescript-mode a7cd7a92a5 167/222: fix(font-lock): prefer fontifying constants over keywords, ELPA Syncer, 2022/02/06
- [nongnu] elpa/typescript-mode 1767de1095 180/222: Merge pull request #129 from emacs-typescript/feature/types-in-declarations, ELPA Syncer, 2022/02/06
- [nongnu] elpa/typescript-mode 0d5c941c4c 195/222: * typescript-mode.el: Use EOS instead of EOL for auto mode regexp., ELPA Syncer, 2022/02/06
- [nongnu] elpa/typescript-mode 7d80174b23 216/222: Skip past ? and ! in typescript--compute-member-expression-indent, ELPA Syncer, 2022/02/06
- [nongnu] elpa/typescript-mode 6918f3f6d7 212/222: Merge pull request #154 from emacs-typescript/feature/build-tasks, ELPA Syncer, 2022/02/06
- [nongnu] elpa/typescript-mode 13e6da6c57 219/222: Merge pull request #157 from rsimoes/patch-1, ELPA Syncer, 2022/02/06
- [nongnu] elpa/typescript-mode a6e0eac105 029/222: Fix wrong cursor position in `typescript-indent-line`, ELPA Syncer, 2022/02/06
- [nongnu] elpa/typescript-mode 0f41709e15 074/222: Fontify @type properly and allow jsdoc one-liners., ELPA Syncer, 2022/02/06
- [nongnu] elpa/typescript-mode 90d9758cfb 035/222: Revert "Fix wrong cursor position in `typescript-indent-line`", ELPA Syncer, 2022/02/06
- [nongnu] elpa/typescript-mode 1cea84486f 064/222: Merge pull request #35 from lddubeau/feature/indent-return-annotations,
ELPA Syncer <=
- [nongnu] elpa/typescript-mode 9ad892fb22 061/222: Add keyword 'object', ELPA Syncer, 2022/02/06
- [nongnu] elpa/typescript-mode e3d2fee6de 004/222: unnecessary for single package file, ELPA Syncer, 2022/02/06
- [nongnu] elpa/typescript-mode 7e8b9641ae 096/222: Mark typescript indent variables as safe for file local customizations, ELPA Syncer, 2022/02/06
- [nongnu] elpa/typescript-mode 813cf4fef3 069/222: Fix endless loop (hang) in indentation-code., ELPA Syncer, 2022/02/06
- [nongnu] elpa/typescript-mode cebfe5952b 114/222: Rename the regexp matching pretty error messages., ELPA Syncer, 2022/02/06
- [nongnu] elpa/typescript-mode 5d5c611e2d 119/222: Add tags in js2-mode, ELPA Syncer, 2022/02/06
- [nongnu] elpa/typescript-mode e608305ade 137/222: checkdoc fixes, ELPA Syncer, 2022/02/06
- [nongnu] elpa/typescript-mode 85504ce34b 138/222: Update build-badge URL., ELPA Syncer, 2022/02/06
- [nongnu] elpa/typescript-mode f6330f420e 144/222: Add a test for #107., ELPA Syncer, 2022/02/06
- [nongnu] elpa/typescript-mode c1aa1b2e7d 149/222: add better generics highlighting, ELPA Syncer, 2022/02/06