emacs-elpa-diffs
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

[nongnu] elpa/swift-mode 25944c2 378/496: Add test for beginning/end-of-


From: ELPA Syncer
Subject: [nongnu] elpa/swift-mode 25944c2 378/496: Add test for beginning/end-of-defun
Date: Sun, 29 Aug 2021 11:34:11 -0400 (EDT)

branch: elpa/swift-mode
commit 25944c2a98a8f78453e14591884a940c64740347
Author: taku0 <mxxouy6x3m_github@tatapa.org>
Commit: taku0 <mxxouy6x3m_github@tatapa.org>

    Add test for beginning/end-of-defun
---
 swift-mode-beginning-of-defun.el                   |  12 +-
 swift-mode-lexer.el                                |   8 +-
 swift-mode.el                                      |   2 +
 .../beginning-of-defun/beginning-of-defun.swift    | 319 +++++++++++++++++++++
 test/swift-mode-test-beginning-of-defun.el         | 242 ++++++++++++++++
 test/swift-mode-test-indent.el                     |   2 +-
 test/swift-mode-test.el                            |   5 +-
 7 files changed, 579 insertions(+), 11 deletions(-)

diff --git a/swift-mode-beginning-of-defun.el b/swift-mode-beginning-of-defun.el
index 1a9d9a3..0bba2b5 100644
--- a/swift-mode-beginning-of-defun.el
+++ b/swift-mode-beginning-of-defun.el
@@ -332,23 +332,23 @@ Intended for internal use."
                          '(\; implicit-\; } anonymous-function-parameter-in
                            outside-of-buffer)))
               (swift-mode:pseudo-implicit-semicolon-p token))))
-    (while (eq (swift-mode:token:type
-                (save-excursion (swift-mode:forward-token)))
-               '\;)
-      (setq token (swift-mode:forward-token)))
     (if (memq (swift-mode:token:type token)
               '(\; anonymous-function-parameter-in))
         (goto-char (swift-mode:token:end token))
       (goto-char (swift-mode:token:start token)))
+    (while (eq (swift-mode:token:type
+                (save-excursion (swift-mode:forward-token)))
+               '\;)
+      (setq token (swift-mode:forward-token)))
     (cond
      ((eq (swift-mode:token:type token) 'outside-of-buffer)
       (forward-comment (- (point)))
-      (when (< (point) pos)
+      (when (<= (point) pos)
         (goto-char (swift-mode:token:end token)))
       token)
      ((eq (swift-mode:token:type token) '})
       (forward-comment (- (point)))
-      (if (< (point) pos)
+      (if (<= (point) pos)
           (progn
             (goto-char (swift-mode:token:end token))
             (swift-mode:end-of-statement))
diff --git a/swift-mode-lexer.el b/swift-mode-lexer.el
index 6a47238..ed9e5fd 100644
--- a/swift-mode-lexer.el
+++ b/swift-mode-lexer.el
@@ -1252,7 +1252,9 @@ If this line ends with a single-line comment, goto just 
before the comment."
         ;; Proceed to the end of the comment.
         (goto-char (swift-mode:chunk:start chunk))
         (forward-comment 1)
-        (end-of-line)))))
+        (end-of-line)
+        (when (and (eobp) (swift-mode:chunk-after))
+          (goto-char (swift-mode:chunk:start (swift-mode:chunk-after))))))))
 
 ;;; Comment or string chunks
 
@@ -1301,8 +1303,8 @@ If this line ends with a single-line comment, goto just 
before the comment."
 If the cursor is outside of strings and comments, return nil.
 
 If PARSER-STATE is given, it is used instead of (syntax-ppss)."
-  (unless parser-state
-    (setq parser-state (syntax-ppss)))
+  (when (or (null parser-state) (number-or-marker-p parser-state))
+    (setq parser-state (save-excursion (syntax-ppss parser-state))))
   (cond
    ((eq (nth 3 parser-state) t)
     (swift-mode:chunk 'multiline-string (nth 8 parser-state)))
diff --git a/swift-mode.el b/swift-mode.el
index 25f5c8f..cbd3257 100644
--- a/swift-mode.el
+++ b/swift-mode.el
@@ -97,6 +97,8 @@
 
 See `forward-sexp for ARG."
   (setq arg (or arg 1))
+  (when (swift-mode:chunk-after)
+    (goto-char (swift-mode:chunk:start (swift-mode:chunk-after))))
   (if (< 0 arg)
       (while (< 0 arg)
         (while (eq (swift-mode:token:type (swift-mode:forward-sexp-1))
diff --git a/test/swift-files/beginning-of-defun/beginning-of-defun.swift 
b/test/swift-files/beginning-of-defun/beginning-of-defun.swift
new file mode 100644
index 0000000..e4e1dfb
--- /dev/null
+++ b/test/swift-files/beginning-of-defun/beginning-of-defun.swift
@@ -0,0 +1,319 @@
+// Foo bar baz.
+
+// Import declarations
+
+/*{*//* aaa */ /* bbb */@Foo import Foundation/*}*/
+/*{*/@Foo
+import Foundation/*}*/
+
+/*{*/class Foo {
+    /*{*/@Foo import Foundation/*}*/
+    /*{*/@Foo
+    import Foundation/*}*/
+}/*}*/
+
+// Constant/variable declarations
+
+/*{*/let x = foo()/*}*/
+/*{*/@Foo
+let
+  y
+  =
+  bar()/*}*/
+
+/*{*/class Foo {
+    /*{*/let x = foo()/*}*/
+    /*{*/@Foo
+    public
+      let
+      y
+      =
+      bar()/*}*/
+
+    /*{*/var a: Int {
+        return 0
+    }/*}*/
+
+    /*{*/var a: Int {
+        /*{*/@Foo
+        get {
+            return 0
+        }/*}*/
+
+        /*{*/@Foo
+        set {
+            foo()
+        }/*}*/
+     }/*}*/
+
+    /*{*/var a = 0 {
+        /*{*/@Foo
+        willSet {
+            foo()
+        }/*}*/
+
+        /*{*/@Foo
+        didSet {
+            foo()
+        }/*}*/
+    }/*}*/
+
+    /*{*/func foo() {
+        let x = foo()
+        let
+          y
+          =
+          bar()
+        while
+          let
+            x
+            =
+            xx,
+          var
+            y
+            =
+            yy,
+          case
+            (
+              a,
+              b
+            )
+            =
+            ab {
+            foo()
+            foo()
+        }
+    }/*}*/
+}/*}*/
+
+// Type alias declarationss
+
+/*{*/@Foo typealias A = B/*}*/
+
+/*{*/@Foo
+typealias
+  A
+  =
+  B/*}*/
+
+/*{*/class Foo {
+    /*{*/@Foo typealias A = B/*}*/
+
+    /*{*/@Foo
+    public
+      typealias
+      A
+      =
+      B/*}*/
+}/*}*/
+
+// Function declarations
+
+/*{*/func foo() {
+}/*}*/
+
+/*{*/@Foo
+func
+foo() {
+}/*}*/
+
+/*{*/class Foo {
+    /*{*/func foo() {
+    }/*}*/
+
+    /*{*/@Foo
+    public
+      func
+      foo<A
+            :
+            X,
+          B,
+          C>(
+        a a
+          :
+          (Int -> [Int])
+          =
+          {
+              x
+              in
+              [
+                x
+              ]
+          }
+      )
+      throws
+      ->
+      @Foo
+      [
+        A
+      ]
+      where
+        A
+          :
+          X
+          ,
+        B
+          ==
+          Int
+    {
+    }/*}*/
+}/*}*/
+
+// Enum declarations
+
+/*{*/enum Foo<A> where A: B {
+    /*{*/case Foo(a: Int)/*}*/
+    /*{*/case Bar(b: Int), Baz/*}*/
+    /*{*/case
+      A(
+        b
+          :
+          Int)
+            ,
+      @Foo
+      indirect
+        B
+        =
+        0/*}*/
+
+    /*{*/func foo() -> a {
+        switch this {
+        case .Foo:
+            return a
+        case
+          let .Bar(a):
+            return a
+        case
+          .Baz(var a):
+            return a
+        }
+    }/*}*/
+}/*}*/
+
+
+// Struct declarations
+
+/*{*/struct Foo {
+}/*}*/
+
+// Class declarations
+
+/*{*/class Foo {
+}/*}*/
+
+/*{*/@Foo
+public
+  final
+  class
+  Foo<A
+        :
+        X
+     ,
+      B
+     ,
+      C>
+  :
+  X
+       where
+         A
+           :
+           X
+           ,
+         B
+           ==
+           Int
+{
+    /*{*/class Foo {
+    }/*}*/
+}/*}*/
+
+// Protocol declarations
+
+/*{*/protocol Foo {
+    /*{*/var x: Int {
+        /*{*/get/*}*/
+        /*{*/set/*}*/
+    }/*}*/
+    /*{*/func foo()/*}*/
+
+    /*{*/associatedtype
+      A
+      :
+      B
+      =
+      C
+      where
+        A
+          :
+          D,
+        A
+          ==
+          E/*}*/
+}/*}*/
+
+// Extension declarations
+/*{*/extension Foo: AAA {
+}/*}*/
+
+// Operator declarations
+/*{*/prefix
+  operator
+  +++/*}*/
+/*{*/postfix
+  operator
+  +++/*}*/
+/*{*/infix
+  operator
+  +++
+  :
+  AAA/*}*/
+
+// Precedence group declarations
+/*{*/precedencegroup Foo {
+    higherThan: AAA, BBB, CCC
+    lowerThan: DDD, EEE, FFF
+    assignment: false
+    associativity: left
+}/*}*/
+
+/*{*/class Foo {
+    // Initializer declarations
+    /*{*/init() {
+        `init`() {
+        }
+    }/*}*/
+
+    // Deinitializer declarations
+    /*{*/deinit() {
+    }/*}*/
+
+    // Subscript declarations
+    /*{*/subscript(x: Int) {
+    }/*}*/
+}/*}*/
+
+// Multiple declaratoins in single line
+
+/*{*/func foo(){};/*}*/ /*{*/func foo(){/*{*/func foo(){}/*}*/};/*}*//*{*/func 
foo(){} ;/*}*/ /*{*/func foo() {} /* */ ;/*}*/ /*{*//* */ func foo() {}/*}*/
+
+// Strings and comments
+
+/*{*/let x = """
+  class Foo {}
+  \(
+    { () in
+        /*{*/class Foo {
+        }/*}*/
+        return 0
+    }()
+  )
+  """/*}*/
+
+// class Foo {}
+
+/*
+ class Foo {
+ }
+ */
+
+// Foo bar baz.
diff --git a/test/swift-mode-test-beginning-of-defun.el 
b/test/swift-mode-test-beginning-of-defun.el
new file mode 100644
index 0000000..129170f
--- /dev/null
+++ b/test/swift-mode-test-beginning-of-defun.el
@@ -0,0 +1,242 @@
+;;; swift-mode-test-beginning-of-defun.el --- Test for swift-mode: 
beginning-of-defun -*- lexical-binding: t -*-
+
+;; Copyright (C) 2017 taku0
+
+;; Authors: taku0 (http://github.com/taku0)
+;;
+;; Version: 4.0.0
+;; Package-Requires: ((emacs "24.4") (seq "2.3"))
+;; Keywords: languages swift
+;; URL: https://github.com/swift-emacs/swift-mode
+
+;; This file is not part of GNU Emacs.
+
+;; This program is free software: you can redistribute it and/or modify
+;; it under the terms of the GNU General Public License as published by
+;; the Free Software Foundation, either version 3 of the License, or
+;; (at your option) any later version.
+
+;; This program is distributed in the hope that it will be useful,
+;; but WITHOUT ANY WARRANTY; without even the implied warranty of
+;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+;; GNU General Public License for more details.
+
+;; You should have received a copy of the GNU General Public License
+;; along with this program.  If not, see <http://www.gnu.org/licenses/>.
+
+;;; Commentary:
+
+;; Test for swift-mode: beginning-of-defun.
+;; Execute swift-mode:run-test:beginning-of-defun interactively or in batch
+;; mode.
+
+;;; Code:
+
+(require 'swift-mode)
+(require 'swift-mode-beginning-of-defun)
+(require 'seq)
+
+(defun swift-mode:run-test:beginning-of-defun
+    (&optional error-buffer error-counts progress-reporter)
+  "Run `beginning-of-defun' test for `swift-mode'.
+
+ERROR-BUFFER is the buffer to output errors.
+ERROR-COUNTS is a association list holding counts of errors.  Updated
+destructively.
+PROGRESS-REPORTER is the progress-reporter."
+  (interactive)
+  (if (not swift-mode:test:running)
+      (swift-mode:run-test '(swift-mode:run-test:beginning-of-defun))
+    (let ((current-line 0)
+          expected-positions-desc
+          expected-positions-asc
+          tests)
+      (setq default-directory
+            (concat (file-name-as-directory swift-mode:test:basedir)
+                    (file-name-as-directory "swift-files")
+                    "beginning-of-defun"))
+      ;; TODO forward-sentence, backward-sentence
+      (dolist (swift-file (file-expand-wildcards "*.swift"))
+        (redisplay)
+        (with-temp-buffer
+          (switch-to-buffer (current-buffer))
+          (insert-file-contents-literally swift-file)
+          (swift-mode)
+          (setq expected-positions
+                (swift-mode:parse-beginning-of-defun-test-file))
+          (setq expected-positions-desc
+                (mapcar (lambda (p)
+                          (list
+                           (nth 0 p)
+                           (nth 2 p)
+                           (nth 4 p)))
+                        expected-positions))
+          (setq expected-positions-asc
+                (mapcar (lambda (p)
+                          (list
+                           (nth 0 p)
+                           (nth 1 p)
+                           (nth 3 p)))
+                        (reverse expected-positions)))
+          (setq test-parameters
+                (list
+                 (list
+                  expected-positions-desc
+                  #'<
+                  (lambda ()
+                    (swift-mode:beginning-of-defun)
+                    (skip-syntax-forward " "))
+                  'beginning-of-defun)
+                 (list
+                  expected-positions-asc
+                  #'>
+                  #'swift-mode:end-of-defun
+                  'end-of-defun)))
+          (setq current-line 0)
+          (while (not (eobp))
+            (when (not noninteractive)
+              (progress-reporter-update progress-reporter))
+            (setq current-line (1+ current-line))
+            (when (looking-at ".*//.*swift-mode:test:eval\\(.*\\)")
+              (eval-region (match-beginning 1) (match-end 1)))
+
+            (dolist (test-parameter test-parameters)
+              (let* ((status (apply
+                              #'swift-mode:test-current-line-beginning-of-defun
+                              swift-file
+                              current-line
+                              error-buffer
+                              test-parameter))
+                     (count-assoc (assq status error-counts)))
+                (setcdr count-assoc (1+ (cdr count-assoc)))))
+            (forward-line)))))))
+
+(defun swift-mode:parse-beginning-of-defun-test-file ()
+  "Parse the current buffer as a test file and return its structure.
+
+The result is a list of remarkable tokens in descendant order.  A remarkable
+token is a list with the follwing elements:
+
+1. Type; one of `beginning-of-defun', `end-of-defun', `{', or `}'
+2. Start position
+3. End position
+4. Nesting level at the start position
+5. Nesting level at the end position
+
+`beginning-of-defun' and `end-of-defun' are represented as /*{*/ and /*}*/,
+respectively, in the test file, and removed from the buffer.
+
+`{' and `}' includes square brackets and parentheses."
+  (save-excursion
+    (goto-char (point-min))
+    (let ((expected-positions
+           (list (list 'beginning-of-defun (point) (point) 0 0)))
+          (depth 0)
+          (pattern (mapconcat #'regexp-quote
+                              '("/*{*/" "/*}*/" "{" "}" "[" "]" "(" ")")
+                              "\\|"))
+          match-string
+          match-beginning
+          match-end)
+      (while (search-forward-regexp pattern nil t)
+        (setq match-string (match-string-no-properties 0))
+        (setq match-beginning (match-beginning 0))
+        (setq match-end (match-end 0))
+        (cond
+         ((equal match-string "/*{*/")
+          (add-to-list 'expected-positions
+                       (list 'beginning-of-defun
+                             match-beginning match-beginning
+                             depth depth))
+          (replace-match ""))
+         ((equal match-string "/*}*/")
+          (add-to-list 'expected-positions
+                       (list 'end-of-defun
+                             match-beginning match-beginning
+                             depth depth))
+          (replace-match ""))
+         ((and (member match-string '("{" "[" "("))
+               (not (swift-mode:chunk-after match-beginning)))
+          (setq depth (1+ depth))
+          (add-to-list 'expected-positions
+                       (list '{ match-beginning match-end (1- depth) depth)))
+         ((and (member match-string '("}" "]" ")"))
+               (not (swift-mode:chunk-after match-end)))
+          (setq depth (1- depth))
+          (add-to-list 'expected-positions
+                       (list '} match-beginning match-end (1+ depth) depth)))))
+      (goto-char (point-max))
+      (add-to-list 'expected-positions
+                   (list 'end-of-defun (point) (point) depth depth))
+      expected-positions)))
+
+(defun swift-mode:test-current-line-beginning-of-defun
+    (swift-file
+     current-line
+     error-buffer
+     expected-positions
+     less-than-function
+     beginning-of-thing-function
+     boundary-symbol)
+  "Run `beginning-of-defun' test for `swift-mode' on current line.
+
+SWIFT-FILE is the filename of the current test case.
+CURRENT-LINE is the current line number.
+ERROR-BUFFER is the buffer to output errors.
+EXPECTED-POSITIONS is a list of remarkable tokens
+\(see `swift-mode:parse-beginning-of-defun-test-file').
+LESS-THAN-FUNCTION is a function returns non-nil iff the firt argument is
+before (or after for `end-of-defun' test) the second argument.
+BEGINNING-OF-THING-FUNCTION is a function goes to the boundary, that is the
+beginning of a defun or the end of the defun..
+BOUNDARY-SYMBOL is the type of expected remarkable token, like
+`beginning-of-defun' or `end-of-defun`'"
+  (forward-line 0)
+  (let ((status 'ok)
+        depth
+        expected-positions-before-point
+        expected-position
+        actual-position)
+    (while (eq status 'ok)
+      (setq expected-positions-before-point
+            (seq-drop-while
+             (lambda (position)
+               (funcall less-than-function (point) (nth 1 position)))
+             expected-positions))
+      (setq depth (or (nth 2 (car expected-positions-before-point)) 0))
+      (setq expected-position
+            (nth 1 (seq-find
+                    (lambda (position)
+                      (setq depth (min depth (nth 2 position)))
+                      (and
+                       (eq (nth 0 position) boundary-symbol)
+                       (funcall less-than-function (nth 1 position) (point))
+                       (<= (nth 2 position) depth)))
+                    expected-positions-before-point
+                    (list nil (point-min) nil))))
+      (setq actual-position (save-excursion
+                              (funcall beginning-of-thing-function)
+                              (point)))
+      (when (/= expected-position actual-position)
+        (setq status 'error)
+        (swift-mode:show-error
+         error-buffer swift-file current-line
+         "error"
+         (concat
+          (symbol-name boundary-symbol)
+          ": at "
+          (prin1-to-string (point))
+          ", expected "
+          (prin1-to-string expected-position)
+          " but "
+          (prin1-to-string actual-position))))
+      (if (eolp)
+          (setq status 'done)
+        (forward-char)))
+    (when (eq status 'done)
+      (setq status 'ok))
+    status))
+
+(provide 'swift-mode-test-beginning-of-defun)
+
+;;; swift-mode-test-beginning-of-defun.el ends here
diff --git a/test/swift-mode-test-indent.el b/test/swift-mode-test-indent.el
index a48236c..f1a0018 100644
--- a/test/swift-mode-test-indent.el
+++ b/test/swift-mode-test-indent.el
@@ -110,7 +110,7 @@ ERROR-BUFFER is the buffer to output errors."
        (if known-bug "warning" "error")
        (concat
         (if known-bug "(knwon bug) " "")
-        "expected "
+        "indent: expected "
         (prin1-to-string original-indent)
         " but "
         (prin1-to-string computed-indent))))
diff --git a/test/swift-mode-test.el b/test/swift-mode-test.el
index 99410ba..8922da2 100644
--- a/test/swift-mode-test.el
+++ b/test/swift-mode-test.el
@@ -32,6 +32,7 @@
 ;;; Code:
 
 (require 'swift-mode-test-indent)
+(require 'swift-mode-test-beginning-of-defun)
 
 (defvar swift-mode:test:basedir
   (file-name-directory (or load-file-name buffer-file-name)))
@@ -48,7 +49,9 @@ Return the error-buffer"
   (erase-buffer)
   (current-buffer))
 
-(defvar swift-mode:tests '(swift-mode:run-test:indent))
+(defvar swift-mode:tests
+  '(swift-mode:run-test:indent
+    swift-mode:run-test:beginning-of-defun))
 
 (defun swift-mode:run-test (&optional tests)
   "Run TESTS for `swift-mode'."



reply via email to

[Prev in Thread] Current Thread [Next in Thread]