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

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

[nongnu] elpa/kotlin-mode c7d5c67ebc 01/10: Improve detection of line co


From: ELPA Syncer
Subject: [nongnu] elpa/kotlin-mode c7d5c67ebc 01/10: Improve detection of line continuation
Date: Tue, 17 Jan 2023 15:08:08 -0500 (EST)

branch: elpa/kotlin-mode
commit c7d5c67ebc36edeccbdab2f88edf32011244e489
Author: taku0 <mxxouy6x3m_github@tatapa.org>
Commit: taku0 <mxxouy6x3m_github@tatapa.org>

    Improve detection of line continuation
    
    Improve regression test to ignore known bug.
    Add pathological regression test.
---
 kotlin-mode.el           |  355 +++++++++-
 test/kotlin-mode-test.el |   75 ++-
 test/pathological.kt     | 1663 ++++++++++++++++++++++++++++++++++++++++++++++
 test/sample.kt           |   79 ++-
 4 files changed, 2080 insertions(+), 92 deletions(-)

diff --git a/kotlin-mode.el b/kotlin-mode.el
index 6b715a5b4d..cd13e797ff 100644
--- a/kotlin-mode.el
+++ b/kotlin-mode.el
@@ -329,53 +329,348 @@
           (kotlin-mode--match-interpolation limit))))))
 
 (defun kotlin-mode--prev-line ()
-  "Moves up to the nearest non-empty line"
-  (if (not (bobp))
-      (progn
-        (forward-line -1)
-        (while (and (looking-at "^[ \t]*$") (not (bobp)))
-          (forward-line -1)))))
-
-(defun kotlin-mode--prev-line-begins (pattern)
-  "Return whether the previous line begins with the given pattern"
-  (save-excursion
-    (kotlin-mode--prev-line)
-    (looking-at (format "^[ \t]*%s" pattern))))
-
-(defun kotlin-mode--prev-line-ends (pattern)
-  "Return whether the previous line ends with the given pattern"
-  (save-excursion
-    (kotlin-mode--prev-line)
-    (looking-at (format ".*%s[ \t]*$" pattern))))
+  "Moves up to the nearest non-empty line."
+  (beginning-of-line)
+  ;; `forward-comment' skips spaces and newlines as well.
+  (forward-comment (- (point))))
 
 (defun kotlin-mode--line-begins (pattern)
-  "Return whether the current line begins with the given pattern"
+  "Return whether the current line begins with the given PATTERN.
+
+Ignore spaces at the beginning of the line."
   (save-excursion
     (beginning-of-line)
     (looking-at (format "^[ \t]*%s" pattern))))
 
+(defun kotlin-mode--line-begins-excluding-comment (pattern)
+  "Return whether the current line begins with the given PATTERN.
+
+Ignore comments and spaces at the beginning of the line."
+  (let ((line-end-position (line-end-position)))
+    (save-excursion
+      (beginning-of-line)
+      (when (nth 4 (syntax-ppss))
+        ;; If the point is inside a comment, goto the beginning of the
+        ;; comment.
+        (goto-char (nth 8 (syntax-ppss))))
+      (forward-comment (point-max))
+      (when (< line-end-position (point))
+        (goto-char line-end-position))
+      (looking-at pattern))))
+
 (defun kotlin-mode--line-ends (pattern)
-  "Return whether the current line ends with the given pattern"
+  "Return whether the current line ends with the given PATTERN.
+
+Ignore spaces at the end of the line."
   (save-excursion
     (beginning-of-line)
     (looking-at (format ".*%s[ \t]*$" pattern))))
 
+(defun kotlin-mode--line-ends-excluding-comment (pattern)
+  "Return whether the current line ends with the given PATTERN.
+
+Ignore comments at the end of the line."
+  (let ((end-position
+         ;; last point where is neither spaces nor comment
+         (max
+          (line-beginning-position)
+          (save-excursion
+            (end-of-line)
+            (when (nth 4 (syntax-ppss))
+              ;; If the point is inside a comment, goto the beginning
+              ;; of the comment.
+              (goto-char (nth 8 (syntax-ppss))))
+            (forward-comment (- (point)))
+            (point)))))
+    (save-excursion
+      (save-restriction
+        (beginning-of-line)
+        (narrow-to-region (point) end-position)
+        (looking-at (format ".*%s$" pattern))))))
+
 (defun kotlin-mode--line-contains (pattern)
-  "Return whether the current line contains the given pattern"
+  "Return whether the current line contains the given PATTERN."
   (save-excursion
     (beginning-of-line)
     (looking-at (format ".*%s.*" pattern))))
 
-(defun kotlin-mode--line-continuation()
+(defun kotlin-mode--line-continuation ()
   "Return whether this line continues a statement in the previous line"
-  (or
-   (and (kotlin-mode--prev-line-begins "\\(if\\|for\\|while\\)[ \t]+(")
-        (kotlin-mode--prev-line-ends ")[[:space:]]*\\(\/\/.*\\|\\/\\*.*\\)?"))
-   (and (kotlin-mode--prev-line-begins "else[ \t]*")
-        (not (kotlin-mode--prev-line-begins "else [ \t]*->"))
-        (not (kotlin-mode--prev-line-ends "{.*")))
-   (or
-    (kotlin-mode--line-begins 
"\\([.=:]\\|->\\|\\(\\(private\\|public\\|protected\\|internal\\)[ 
\t]*\\)?[sg]et\\b\\)"))))
+  (let ((case-fold-search nil))
+    (cond
+     ;; Tokens that end a statement
+     ((save-excursion
+        (kotlin-mode--prev-line)
+        (kotlin-mode--line-ends-excluding-comment
+         (rx (group
+              (or
+               ".*"
+               (seq word-start
+                    (or "return" "continue" "break")
+                    word-end))))))
+      nil)
+
+     ;; Modifiers, that cannot end a statement.
+     ((save-excursion
+        (kotlin-mode--prev-line)
+        (kotlin-mode--line-ends-excluding-comment
+         (rx (group (seq word-start
+                         (or
+                          "public" "private" "protected"
+                          "internal" "enum" "sealed" "annotation"
+                          "data" "inner" "tailrec" "operator" "inline"
+                          "infix" "external" "suspend" "override"
+                          "abstract" "final" "open" "const" "lateinit"
+                          "vararg" "noinline" "crossinline" "reified"
+                          "expect" "actual")
+                         word-end)))))
+      t)
+
+     ;; Tokens that start a statement that have lower priority than modifiers.
+     ((kotlin-mode--line-begins-excluding-comment
+       (rx (group (seq word-start
+                       (or
+                        "public" "private" "protected" "internal"
+                        "enum" "sealed" "annotation" "data" "inner"
+                        "tailrec" "operator" "inline" "infix"
+                        "external" "override" "abstract" "final"
+                        "open" "const" "lateinit" "vararg" "noinline"
+                        "crossinline" "reified" "expect" "actual"
+                        "package" "import" "interface" "val" "var"
+                        "typealias" "constructor" "companion" "init"
+                        "is" "in" "out" "for" "while" "do")
+                       word-end))))
+      nil)
+
+     ((and (kotlin-mode--line-begins-excluding-comment
+            (rx (group (seq word-start "class" word-end))))
+           (not
+            (save-excursion
+              (kotlin-mode--prev-line)
+              (kotlin-mode--line-ends-excluding-comment (rx (group "::"))))))
+      nil)
+
+     ;; Tokens that cannot end a statement
+     ((save-excursion
+        (kotlin-mode--prev-line)
+        (kotlin-mode--line-ends-excluding-comment
+         (rx (group
+              (or
+               (any "-%*./:=+&|<@")
+               "->"
+               (seq word-start
+                    "as?")
+               (seq "!is"
+                    "!in"
+                    word-end)
+               (seq word-start
+                    (or
+                     "package" "import" "class" "interface" "fun"
+                     "object" "val" "var" "typealias" "constructor"
+                     "by" "companion" "init" "where" "if" "else"
+                     "when" "try" "catch" "finally" "for" "do" "while"
+                     "throw" "as" "is" "in" "out")
+                    word-end))))))
+      t)
+
+     ;; Tokens that cannot start a statement
+     ((kotlin-mode--line-begins-excluding-comment
+       (rx (group
+            (or
+             (any ".:=<?&|")
+             "->"
+             (seq word-start "as?")
+             (seq word-start
+                  (or "get" "set" "as" "by" "where")
+                  word-end)))))
+      t)
+
+     (t nil))))
+
+(defun kotlin-mode--base-indentation ()
+  "Return the indentation level of the current line based on brackets only,
+   i.e. ignoring 'continuation' indentation."
+  (cond ((kotlin-mode--line-continuation)
+         (- (current-indentation) kotlin-tab-width))
+        ((kotlin-mode--in-comment-block)
+         (- (current-indentation) 1))
+        (t
+         (current-indentation))))
+
+(defclass kotlin-mode--bracket-counter ()
+  ((count :initarg :count
+          :initform 0
+          :type integer
+          :documentation "The net bracket count (+1 for open, -1 for close).")
+   (indent :initarg :indent
+           :initform 0
+           :type integer
+           :documentation "The indentation based on bracket layout.")
+   (finished :initarg :finished
+             :initform nil
+             :type boolean
+             :documentation "Whether the counting has finished.")
+   (use-base :initarg :use-base
+             :initform t
+             :type boolean
+             :documentation "Whether to factor out extra indentations."))
+  "A class for counting brackets to find the appropriate bracket-based indent.
+   The logic here involves keeping track of the net-bracket-count,
+   defined as the number of open-brackets minus the number of close-brackets.
+   We scroll backwards until the net-bracket-count is zero, and this point
+   determines the desired indentation level for the current line.")
+
+(defun kotlin-mode--count-to-line-start (counter)
+  "Count the brackets on the current line, starting from the
+cursor position, and working backward, incrementing the count +1
+for open-brackets, -1 for close-brackets.
+
+Mark the COUNTER finished, set indentation, and return as soon as
+the overall count exceeds zero.  If the counter is zero at the
+beginning of the line, Mark the counter finished and set
+indentation.  If we hit a beginning of line but the counter is
+negative, just return without marking finished."
+  (when (nth 4 (syntax-ppss))
+    ;; If the point is inside a comment, goto the beginning of the comment.
+    (goto-char (nth 8 (syntax-ppss))))
+  (save-excursion
+    (let ((line-beginning-position (line-beginning-position)))
+      (while (and (<= (oref counter count) 0) (not (bolp)))
+        (forward-comment (- (point)))
+        (backward-char)
+        (when (< (point) line-beginning-position)
+          (goto-char line-beginning-position))
+        (cond ((eq (char-syntax (char-after)) ?\()
+               (cl-incf (oref counter count)))
+              ((eq (char-syntax (char-after)) ?\))
+               (cl-decf (oref counter count))))))
+    ;; We are at the beginning of the line, or just before an
+    ;; unmatching open bracket.
+    (cond
+     ;; If the net-bracket-count is zero, use this indentation
+     ((= (oref counter count) 0)
+      (oset counter finished t)
+      (if (oref counter use-base)
+          ;; Indenting a line that is neither close bracket nor the
+          ;; first element of a block or a list.  Found the previous
+          ;; line.  So align with the previous line, without effect of
+          ;; continued expression at the previous line.
+          (kotlin-mode--add-indent counter (kotlin-mode--base-indentation))
+        ;; Indenting close bracket or the first element of a block or
+        ;; a list.  So align with this line, optionally with extra
+        ;; indentation.
+        (kotlin-mode--add-indent counter (current-indentation))))
+     ;; If we've now counted more open-brackets than close-brackets,
+     ;; use the indentation of the content immediately following the
+     ;; final open-bracket.
+     ;;
+     ;; Example:
+     ;;
+     ;; Suppose indenting "bar2()" in the following example:
+     ;;
+     ;; foo(  bar1(),
+     ;;       bar2())
+     ;;
+     ;; We are at just before the open bracket of "foo".  So skip the
+     ;; open bracket and spaces, then align "bar2()" with "bar1()".
+     ((> (oref counter count) 0)
+      (oset counter finished t)
+      (forward-char)
+      (skip-syntax-forward "(")
+      (skip-syntax-forward "-")
+      (kotlin-mode--add-indent counter (current-column))))))
+
+(defun kotlin-mode--count-leading-close-brackets (counter)
+  "Adjust COUNTER when indenting close brackets.
+
+This function should be called at the line being indented.
+
+Example:
+Suppose indenting the closing bracket of \"bar\" in the following example:
+
+fun foo() {
+    bar {
+      baz()
+    } // Indenting here
+}
+
+This function decrements the counter, so that
+`kotlin-mode--count-to-line-start' should not stop at the line
+\"baz()\", but goto the line \"bar {\", so that the close bracket
+aligned with \"bar {\"."
+
+  (save-excursion
+    (skip-syntax-forward "-")
+    (when (looking-at "\\s)")
+      (oset counter use-base nil)
+      (kotlin-mode--subtract-count counter (skip-syntax-forward ")")))))
+
+(defun kotlin-mode--count-trailing-open-brackets (counter)
+  "Adjust COUNTER when indenting the first element of a block or list.
+
+This function should be called before calling
+`kotlin-mode--count-to-line-start', with the point at the end of
+the previous line of the line being indented.
+
+If the bracket count is at zero, and there are open-brackets at
+the end of the line, do not count them, but add a single
+indentation level. If bracket count is at zero, we are not
+indenting close brackets.
+
+Example:
+
+Suppose indenting \"baz()\" in the following example:
+
+fun foo() {
+    bar {
+        baz()
+    }
+}
+
+This function is called with the point at the end of the line
+\"bar {\". This function skips \"{\" backward and add indentation
+amount `kotlin-tab-width', say 4.  Then
+`kotlin-mode--count-to-line-start' seeks to the
+beginning-of-line.  So the final indentation is 8, that is the
+sum of indentation of bar and extra indentation.
+
+On the other hand, when indenting \"baz2()\" in the following
+line, keep cursor and indentation level as is because
+\"bar(baz1(),\" does not end with open brackets.  Then
+`kotlin-mode--count-to-line-start' stops at the close bracket of
+\"bar(\".  So \"baz2()\" is aligned with \"baz1()\".
+
+fun foo() {
+    bar(baz1(),
+        baz2())
+}"
+  ;; Ignore comments and spaces at the end of the line.
+  ;; Example:
+  ;; fun foo() { // ignore comments here
+  ;;     bar()
+  ;; }
+  (when (nth 4 (syntax-ppss))
+    ;; If the point is inside a comment, goto the beginning of the
+    ;; comment.
+    (goto-char (nth 8 (syntax-ppss))))
+  (forward-comment (- (point)))
+
+  (when (and (= (oref counter count) 0)
+             (not (= (skip-syntax-backward "(") 0)))
+    (kotlin-mode--add-indent counter kotlin-tab-width)
+    (oset counter use-base nil)))
+
+(defun kotlin-mode--add-count (counter val)
+  (cl-incf (oref counter count) val))
+
+(defun kotlin-mode--subtract-count (counter val)
+  (cl-decf (oref counter count) val))
+
+(defun kotlin-mode--add-indent (counter val)
+  (cl-incf (oref counter indent) val))
+
+(defun kotlin-mode--finished (counter)
+  (oref counter finished))
 
 (defun kotlin-mode--in-comment-block ()
   "Return whether the cursor is within a standard comment block structure
diff --git a/test/kotlin-mode-test.el b/test/kotlin-mode-test.el
index 9749006f2f..897a8f88e0 100644
--- a/test/kotlin-mode-test.el
+++ b/test/kotlin-mode-test.el
@@ -181,25 +181,56 @@ println(arg)
     (forward-line)))
 
 (ert-deftest kotlin-mode--sample-test ()
-  (with-temp-buffer
-    (insert-file-contents "test/sample.kt")
-    (goto-char (point-min))
-    (kotlin-mode)
-    (setq-local indent-tabs-mode nil)
-    (setq-local tab-width 4)
-    (setq-local kotlin-tab-width 4)
-    (while (not (eobp))
-      (let ((expected-line (thing-at-point 'line)))
-
-        ;; Remove existing indentation
-        (beginning-of-line)
-        (delete-region (point) (progn (skip-chars-forward " \t") (point)))
-
-        ;; Indent the line
-        (kotlin-mode--indent-line)
-
-        ;; Check that the correct indentation is re-applied
-        (should (equal expected-line (thing-at-point 'line)))
-
-        ;; Go to the next non-empty line
-        (next-non-empty-line)))))
+  (dolist (filename '("test/sample.kt" "test/pathological.kt"))
+    (with-temp-buffer
+      (insert-file-contents filename)
+      (goto-char (point-min))
+      (kotlin-mode)
+      (setq-local indent-tabs-mode nil)
+      (setq-local tab-width 4)
+      (setq-local kotlin-tab-width 4)
+
+      (while (not (eobp))
+        (back-to-indentation)
+        (let (;; (thing-at-point 'line) returns string with property.
+              (expected-line (buffer-substring-no-properties
+                              (line-beginning-position)
+                              (line-end-position)))
+              actual-line
+              (original-indent (current-column))
+              (known-bug (looking-at ".*//.*KNOWN_BUG")))
+          ;; Remove existing indentation, or indent to column 1 if
+          ;; expected indentation is column 0.
+          (if (= original-indent 0)
+              (indent-line-to 1)
+            (delete-horizontal-space))
+
+          ;; Indent the line
+          (kotlin-mode--indent-line)
+
+          (setq actual-line (buffer-substring-no-properties
+                             (line-beginning-position)
+                             (line-end-position)))
+
+          ;; Check that the correct indentation is re-applied
+          (if known-bug
+              (if (equal expected-line actual-line)
+                  (message "%s:%s:info: KNOWN_BUG is fixed somehow"
+                           filename
+                           (line-number-at-pos))
+                (back-to-indentation)
+                (message "%s:%s:warn: (known bug) expected indentation to 
column %d but %d"
+                         filename
+                         (line-number-at-pos)
+                         original-indent
+                         (current-column)))
+            (should
+             (equal
+              (format "%s:%s: %s" filename (line-number-at-pos) expected-line)
+              (format "%s:%s: %s" filename (line-number-at-pos) actual-line))))
+
+          ;; Restore to original indentation for KNOWN_BUG line.
+          (indent-line-to original-indent)
+
+          ;; Go to the next non-empty line
+          (next-non-empty-line))))))
diff --git a/test/pathological.kt b/test/pathological.kt
new file mode 100644
index 0000000000..ec3421fd4a
--- /dev/null
+++ b/test/pathological.kt
@@ -0,0 +1,1663 @@
+#!/usr/bin/kotlinc -script
+
+// fileAnnotation
+@file
+    :
+    [
+        A(a = 1) // No Comma here
+        B
+            .
+            C
+            .
+            D // No Comma here
+        E
+    ]
+
+@file
+    :
+    Foo
+    .
+    Bar
+    .
+    Baz
+
+// packageHeader
+package foo // Line breaks are prohibited after "package".
+    .bar // Line breaks are prohibited after dot.
+    .baz
+
+// importList, importHeader
+import a // Line breaks are prohibited after "import".
+    .b // Line breaks are prohibited after dot.
+    .c
+    .*
+
+// importAlias
+import a
+    . b
+    . c
+    as d
+
+// typeAlias
+@A
+public
+    typealias
+    A
+    <
+        B, // KNOWN_BUG
+        C // KNOWN_BUG
+    > // KNOWN_BUG
+    = // KNOWN_BUG
+    D
+
+// classDeclaration
+
+@A
+public
+    sealed
+    class
+    A
+    <
+        A, // KNOWN_BUG
+        B // KNOWN_BUG
+    > // KNOWN_BUG
+    // primaryConstructor
+    public
+    constructor // KNOWN_BUG
+    (
+        // classParameters
+        val
+            x
+            :
+            Foo
+            =
+            foo,
+        var
+            y
+            :
+            Foo
+            =
+            foo
+    )
+    :
+    // delegationSepcifiers
+    Base
+    by
+    x +
+    x,
+    B, // KNOWN_BUG
+    C,
+    D
+        .
+        (Int)
+        ->
+        Int
+    where // KNOWN_BUG
+        @A // KNOWN_BUG
+        A // KNOWN_BUG
+            :
+            A,
+        B
+            :
+            B {
+
+    public // KNOWN_BUG
+        interface
+        A {
+       fun a(): Int // KNOWN_BUG
+    } // KNOWN_BUG
+
+    // typeParameters
+    data
+        class
+        Bar<
+            @A // KNOWN_BUG
+            out // KNOWN_BUG
+                A
+                :
+                A,
+            @A
+            in
+                A
+                :
+                A
+        > // KNOWN_BUG
+    { // brace on its own line // KNOWN_BUG
+        fun a() {
+        }
+    }
+
+    inner
+        enum
+        class
+        A(val x: Int) {
+        // enumClassBody // KNOWN_BUG
+        A(1), B(1), // KNOWN_BUG
+        C(1) {
+            override fun a() = 2
+        }, D(1),
+        E(1);
+
+        fun a(): Int = x
+    } // KNOWN_BUG
+
+    // anonymousInitializer
+    init {
+        a()
+    }
+
+    // companionObject
+    public
+        companion
+        object
+        A
+        :
+        B {
+        fun foo() { // KNOWN_BUG
+        }
+    } // KNOWN_BUG
+
+    // functionDeclaration
+    public
+        fun
+        <
+            A // KNOWN_BUG
+        >
+        A
+        . // KNOWN_BUG
+        foo
+        // functionValueParameters // KNOWN_BUG
+        ( // KNOWN_BUG
+            a: Int = 1
+        )
+        : // KNOWN_BUG
+        A
+        where
+        A : A {
+        a() // KNOWN_BUG
+    } // KNOWN_BUG
+
+    fun
+        foo(x)
+        =
+        x + 1
+
+    // propertyDeclaration
+    public
+        val
+        <
+          A // KNOWN_BUG
+        > // KNOWN_BUG
+        A
+        . // KNOWN_BUG
+        @A
+        a // KNOWN_BUG
+        : // KNOWN_BUG
+        A
+        where
+        A
+        :
+        A
+        =
+        a
+        get() = 1
+        set(value) {
+            foo(value)
+        }
+
+    // delegated property
+    var
+        x : Int
+        by
+        foo
+
+    // multiVariableDeclaration
+    public
+        var
+        (
+            x: Int,
+            y: Int
+        )
+
+    // getter/setter with default implementation
+    var x = 1
+        @A get // KNOWN_BUG
+        @A set
+
+    // objectDeclaration // KNOWN_BUG
+    public // KNOWN_BUG
+        object
+        Foo
+        :
+        Bar {
+        fun foo() { // KNOWN_BUG
+        }
+    } // KNOWN_BUG
+
+    // secondaryConstructor
+    public
+        constructor
+        (
+        )
+        :
+        this
+        ( // KNOWN_BUG
+            1
+        ) {
+        a() // KNOWN_BUG
+    } // KNOWN_BUG
+
+    public // KNOWN_BUG
+        constructor
+        (
+        )
+        :
+        super
+        ( // KNOWN_BUG
+            1
+        )
+
+    // dynamic type // KNOWN_BUG
+    var x: dynamic = 1 // KNOWN_BUG
+
+    // nullableType
+    var
+        x
+        :
+        A
+        <
+            X, // KNOWN_BUG
+            *, // KNOWN_BUG
+            out
+                Y,
+            in
+                Z
+        > // KNOWN_BUG
+        . // KNOWN_BUG
+        B
+        .
+        C
+        <
+            X // KNOWN_BUG
+        >
+        ? // KNOWN_BUG
+        ?
+        ?
+        =
+        null
+
+    var
+        x
+        :
+        (
+            Int
+        )
+        ?
+        =
+        null
+
+    // functionType
+    var
+        f
+        :
+        // parehthesized nullable receiver type
+        (
+            A
+        )
+        ?
+        .
+        (
+            Int
+        )
+        ->
+        (
+            Int
+        )
+        ->
+        C
+} // KNOWN_BUG
+
+// statements // KNOWN_BUG
+fun foo() { // KNOWN_BUG
+    //explicit semicolons
+    a();
+    b();
+    c();
+
+    // annotation
+    @A
+    // label
+    aaa@
+    a() // KNOWN_BUG
+
+    // forStatement // KNOWN_BUG
+    for ( // KNOWN_BUG
+        @A
+        a
+            :
+            A
+        in
+            aaa
+    ) {
+        a()
+    }
+
+    for
+        (
+            @A
+            (x, y)
+            in
+                aaa
+        )
+    {
+        a()
+    }
+
+    for (
+        a in aaa
+    )
+        a() // KNOWN_BUG
+
+    // whileStatement // KNOWN_BUG
+    while ( // KNOWN_BUG
+        a()
+    ) {
+        a()
+    }
+
+    while
+        (
+            a()
+        )
+    {
+        a()
+    }
+
+    while (
+        a()
+    )
+        a() // KNOWN_BUG
+
+    while ( // KNOWN_BUG
+        a()
+    )
+        ; // KNOWN_BUG
+
+    // doWhileStatement // KNOWN_BUG
+    do { // KNOWN_BUG
+        a()
+    } while (
+        a()
+    )
+
+    do
+    { // KNOWN_BUG
+        a()
+    }
+    while // KNOWN_BUG
+        (
+            a()
+        )
+
+    do
+        a()
+    while (a())
+
+    do
+    while (a())
+
+    // assignment
+    (x, y) = // Line breaks are prohibited before assignment operators.
+        a()
+
+    aaa[x] =
+        1
+
+    a
+        .
+        b
+        ?.
+        c
+        .
+        d =
+        e
+
+    a
+        .
+        b +=
+        1
+
+    a
+        .
+        b -=
+        1
+
+    a
+        .
+        b *=
+        1
+
+    a
+        .
+        b %=
+        1
+
+    // expression
+    // various operators
+    val x =
+        a
+        ||
+        b
+        &&
+        c
+
+    val x =
+        a == // Line breaks are prohibited before equality operators
+        b
+
+    val x =
+        a !=
+        b
+
+    val x =
+        a ===
+        b
+
+    val x =
+        a !==
+        g
+
+    val x =
+        a < // Line breaks are prohibited before comparison operators
+        b
+
+    val x =
+        a >
+        b // KNOWN_BUG
+
+    val x = // KNOWN_BUG
+        a <=
+        b
+
+    val x =
+        a >=
+        b
+
+    val x =
+        a in // Line breaks are prohibited before in/is operators
+        b
+
+    val x =
+        a
+        !in // KNOWN_BUG
+        b // KNOWN_BUG
+
+    when (a()) {
+        1 -> a()
+        // Line breaks are prohibited before in/is operators, So the following
+        // line should not be indented.
+        in aaa -> a()
+    }
+
+    val x =
+        a is
+        b
+
+    val x =
+        a !is
+        b
+
+    when (a()) {
+        1 -> a()
+        // Line breaks are prohibited before in/is operators, So the following
+        // line should not be indented.
+        is X -> a()
+    }
+
+    val x =
+        a
+        ?:
+        b
+
+    // infixFunctionCall
+    val x =
+        a shl // Line breaks are allowed after infix function.
+        b // KNOWN_BUG
+
+    // This is not a infix function call; line breaks are // KNOWN_BUG
+    // prohibited before infix function. // KNOWN_BUG
+    val x = // KNOWN_BUG
+        a
+    f (b) // So this line should not indented.
+
+    val x =
+        a .. // Line breaks are prohibited before range operator.
+        b
+
+    val x =
+        a + // Line breaks are prohibited before additive operators.
+        b -
+        c
+
+    a()
+    +a() // So this line should not be indented.
+    -a() // Nor should this line.
+
+    val x =
+        a * // Line breaks are prohibited before multiplicative operators.
+        b /
+        c %
+        d
+
+    val x =
+        a
+        as
+        A
+        as?
+        B
+
+    // prefixUnaryExpression
+    val x =
+        @a
+        a@ // label // KNOWN_BUG
+        + // KNOWN_BUG
+        -
+        ++
+        a
+
+    val x =
+        --
+        a
+
+    val x =
+        !
+        a // KNOWN_BUG
+
+    // postfixUnaryExpression // KNOWN_BUG
+    val x = // KNOWN_BUG
+        a++ // Line breaks are prohibited before postfix operators.
+
+    val x =
+        a
+    ++ a // So this line should not be indented.
+
+    val x =
+        a--
+
+    val x =
+        a
+    -- a // This line too.
+
+    val x =
+        a!!
+
+    val x =
+        f< // Line breaks are prohibited before type arguments.
+            A // KNOWN_BUG
+        >( // Line breaks are prohibited before function arguments.
+            x
+        )[ // Line breaks are prohibited before subscript.
+            x
+        ]
+        . // KNOWN_BUG
+        a
+        .
+        b
+
+    // lambda arguments
+    val x = f()
+    @A
+    a@
+    { // KNOWN_BUG
+        a()
+    }
+
+    val x = f() @A a@ { // KNOWN_BUG
+        a()
+    }
+
+    val x = f
+    @A
+    a@
+    { // KNOWN_BUG
+        a()
+    }
+
+    val x = f @A a@ { // KNOWN_BUG
+        a()
+    }
+
+    val x =
+        f // Line breaks are prohibited before function arguments.
+    (1 + 1).also { print(it) } // So this line should not be indented.
+
+    val x =
+        a // Line breaks are prohibited before function arguments.
+    [g()].forEach { print(it) } // So this line should not be indented.
+
+    // parenthesizedExpression
+    val x = (
+        a()
+    )
+
+    // collectionLiteral
+    @A(x = [
+           1, 2, 3,
+           4, 5, 6,
+           7, 8, 9
+    ])
+    a()
+
+    // CharacterLiteral
+    val x =
+        'a'
+
+    val x =
+        '\''
+
+    val x =
+        '"'
+
+    // stringLiteral
+    val x = "abc\"def${
+        foo("abc") // KNOWN_BUG
+    }ghi${ // KNOWN_BUG
+        "aaa\${ // dollar sign cannot be escaped // KNOWN_BUG
+            1 // KNOWN_BUG
+        }bbb" // KNOWN_BUG
+    }jkl" // KNOWN_BUG
+
+    val x = """a
+               "b" // KNOWN_BUG
+               c${
+        foo("""a // KNOWN_BUG
+                b // KNOWN_BUG
+                  c // KNOWN_BUG
+            """) // KNOWN_BUG
+    }d // KNOWN_BUG
+    e // KNOWN_BUG
+    f${
+        """aaa\${ // KNOWN_BUG
+            1 // KNOWN_BUG
+        }bbb""" // KNOWN_BUG
+    }ghi""" // KNOWN_BUG
+
+    val x =
+        a("'")
+
+    // lambdaLiteral
+    val f: () -> Unit = {
+        a()
+        a()
+        a()
+    }
+
+    val f: () -> Unit = { ->
+        a() // KNOWN_BUG
+        a() // KNOWN_BUG
+        a()
+    }
+
+    val f: () -> Unit = {
+        -> // KNOWN_BUG
+        a()
+        a() // KNOWN_BUG
+        a()
+    }
+
+    val f: () -> Unit = { x,
+                          @A
+                          y
+                              :
+                              Int,
+                          (
+                              z1,
+                              z2
+                          )
+                              :
+                              AAA
+                              ->
+        a() // KNOWN_BUG
+        a() // KNOWN_BUG
+        a()
+    }
+
+    val f: () -> Unit = {
+        x,
+        y,
+        z
+        -> // KNOWN_BUG
+        a()
+        a() // KNOWN_BUG
+        a()
+    }
+
+    val f =
+        fun
+        A
+        .
+        (
+            x: Int
+        )
+        :
+        AAA
+        where
+        A
+        :
+        A,
+        B // KNOWN_BUG
+        : // KNOWN_BUG
+        B {
+        a() // KNOWN_BUG
+    } // KNOWN_BUG
+
+    // functionLiteral
+    val f = fun
+    {  // KNOWN_BUG
+        a()
+    }
+
+    // objectLiteral // KNOWN_BUG
+    val x = // KNOWN_BUG
+        object
+        :
+        A,
+        B // KNOWN_BUG
+            by
+            b,
+        C {
+        fun foo() { // KNOWN_BUG
+        }
+    } // KNOWN_BUG
+
+    val x = object // KNOWN_BUG
+    { // KNOWN_BUG
+        fun foo() {
+        }
+    }
+
+    // thisExpression // KNOWN_BUG
+    val x = // KNOWN_BUG
+        this
+
+    val x =
+        this@Foo
+
+    // superExpression
+    val x =
+        super
+
+    val x =
+        super@Foo
+
+    val x =
+        super<
+            Int // KNOWN_BUG
+        >@Foo
+
+     // ifExpression // KNOWN_BUG
+     val x = if ( // KNOWN_BUG
+         a
+     ) {
+         a()
+     }
+
+     val x = if
+         (
+             a
+         )
+     {
+         a()
+     }
+
+     val x = if (
+         a
+     )
+         a() // KNOWN_BUG
+
+     val x = if ( // KNOWN_BUG
+         a
+     )
+         ; // KNOWN_BUG
+
+     val x = if ( // KNOWN_BUG
+         a
+     ) {
+         a()
+     } else {
+         a()
+     }
+
+     val x = if
+         (
+             a
+
+         )
+     {
+         a()
+     }
+     else
+     { // KNOWN_BUG
+         a()
+     }
+
+     val x = if ( // KNOWN_BUG
+         a
+     )
+         a() // KNOWN_BUG
+     else // KNOWN_BUG
+         a()
+
+     val x = if (
+         a
+     )
+         ; // KNOWN_BUG
+     else // KNOWN_BUG
+         ;
+
+     val x = if (
+         a
+     )
+     else
+         ;
+
+     // whenExpression
+
+     val x = when (
+         @A
+         val
+             a
+             =
+             a()
+     ) {
+         a(), b(),
+         c(), d()
+             ->
+         { // KNOWN_BUG
+             a()
+         }
+
+         in // KNOWN_BUG
+             a()
+             ->
+         { // KNOWN_BUG
+         }
+
+         is // KNOWN_BUG
+             A
+             ->
+         { // KNOWN_BUG
+         }
+
+         a() // KNOWN_BUG
+             ->
+             a()
+
+         else
+             ->
+         { // KNOWN_BUG
+         }
+     }
+
+     val x = when
+         (
+             a()
+         )
+     {
+         a -> 1
+     }
+
+     // tryExpression
+     val x = try {
+         a()
+     } catch(@A e: E) {
+         a()
+     } catch(@A e: E) {
+         a()
+     } finally {
+         a()
+     }
+
+     val x = try
+     { // KNOWN_BUG
+         a()
+     }
+     catch // KNOWN_BUG
+         (
+             @A e: E
+         )
+     {
+         a()
+     }
+     finally
+     { // KNOWN_BUG
+         a()
+     }
+
+     val x = try { // KNOWN_BUG
+         a()
+     } finally {
+         a()
+     }
+
+     val x = try
+     { // KNOWN_BUG
+         a()
+     }
+     finally // KNOWN_BUG
+     { // KNOWN_BUG
+         a()
+     }
+
+     // jumpExpression // KNOWN_BUG
+     val x = // KNOWN_BUG
+         throw
+         a()
+
+     val x =
+         return a() // Line breaks are prohibited after return.
+
+     val x =
+         return // Line breaks are prohibited after return.
+     a() // So this line should not be indented.
+
+     val x =
+         return@A a() // Line breaks are prohibited after return.
+
+     val x =
+         return@A // Line breaks are prohibited after return.
+     a() // So this line should not be indented.
+
+     val x =
+         continue
+
+     val x =
+         continue@A
+
+     val x =
+         break
+
+     val x =
+         break@A
+
+     // callableReference
+     val x =
+         Foo
+         ::
+         foo
+
+     val x =
+         Foo
+         ::
+         class
+
+     // typeModifier // KNOWN_BUG
+     val f:
+         suspend
+         () -> Unit
+         =
+         suspend
+     { // KNOWN_BUG
+         a()
+     }
+}
+
+class Foo: Base {
+    // memberModifier
+    public
+        override
+        fun f() {
+    } // KNOWN_BUG
+
+    public
+        lateinit
+        var x: Int
+
+
+    // visibilityModifier
+    override
+        public
+        fun f() {
+    } // KNOWN_BUG
+
+    override
+        private
+        fun f() {
+    } // KNOWN_BUG
+
+    override
+        internal
+        fun f() {
+    } // KNOWN_BUG
+
+    override
+        protected
+        fun f() {
+    } // KNOWN_BUG
+
+    // functionModifier
+    public
+        tailrec
+        infix
+        inline
+        fun A.f(): A {
+        return a() // KNOWN_BUG
+    } // KNOWN_BUG
+
+    public
+        operator
+        fun A.unaryPlus(): A {
+        return a() // KNOWN_BUG
+    } // KNOWN_BUG
+
+    public
+        suspend
+        fun foo() {
+        a() // KNOWN_BUG
+    } // KNOWN_BUG
+}
+
+public
+    external
+    fun foo() {
+    a() // KNOWN_BUG
+} // KNOWN_BUG
+
+class Foo {
+    // propertyModifier
+    public
+        const
+        val
+        x = 1
+}
+
+// inheritanceModifier
+public
+    abstract
+    class Foo {
+        fun foo() {
+    } // KNOWN_BUG
+} // KNOWN_BUG
+
+public
+    final
+    class Foo {
+    fun foo() { // KNOWN_BUG
+    }
+} // KNOWN_BUG
+
+public
+    open
+    class Foo {
+    fun foo() { // KNOWN_BUG
+    }
+} // KNOWN_BUG
+
+class Foo {
+    // parameterModifier
+    fun foo(
+        @A
+        crossinline
+            body: () -> Unit
+    ) {
+    }
+
+    fun foo(
+        @A
+        noinline
+            body: () -> Unit
+    ) {
+    }
+
+    fun foo(
+        @A
+        vararg
+            a: A
+    ) {
+    }
+
+    // reificationModifier
+    inline fun <
+        @A
+        reified // KNOWN_BUG
+            T
+    > foo() { // KNOWN_BUG
+        a()
+    }
+}
+
+// platformModifier
+public
+    expect
+    class Foo {
+    fun foo() // KNOWN_BUG
+} // KNOWN_BUG
+
+public
+    actual
+    class Foo {
+    fun foo() // KNOWN_BUG
+} // KNOWN_BUG
+
+// various identifiers
+
+val `abc def 'ghi "aaa ${ aaa \` = // backquotes cannot be escaped
+    a() // KNOWN_BUG
+
+// UNICODE_CLASS_ND
+val 
_0123456789٠١٢٣٤٥٦٧٨٩۰۱۲۳۴۵۶۷۸۹߀߁߂߃߄߅߆߇߈߉०१२३४५६७८९০১২৩৪৫৬৭৮৯੦੧੨੩੪੫੬੭੮੯૦૧૨૩૪૫૬૭૮૯୦୧୨୩୪୫୬୭୮୯௦௧௨௩௪௫௬௭௮௯౦౧౨౩౪౫౬౭౮౯೦೧೨೩೪೫೬೭೮೯൦൧൨൩൪൫൬൭൮൯෦෧෨෩෪෫෬෭෮෯๐๑๒๓๔๕๖๗๘๙໐໑໒໓໔໕໖໗໘໙༠༡༢༣༤༥༦༧༨༩၀၁၂၃၄၅၆၇၈၉႐႑႒႓႔႕႖႗႘႙០១២៣៤៥៦៧៨៩᠐᠑᠒᠓᠔᠕᠖᠗᠘᠙᥆᥇᥈᥉᥊᥋᥌᥍᥎᥏᧐᧑᧒᧓᧔᧕᧖᧗᧘᧙᪀᪁᪂᪃᪄᪅᪆᪇᪈᪉᪐᪑᪒᪓᪔᪕᪖᪗᪘᪙᭐᭑᭒᭓᭔᭕᭖᭗᭘᭙᮰᮱᮲᮳᮴᮵᮶᮷᮸᮹᱀᱁᱂᱃᱄᱅᱆᱇᱈᱉᱐᱑᱒᱓᱔᱕᱖᱗᱘᱙꘠꘡꘢꘣꘤꘥꘦꘧꘨꘩꣐꣑꣒꣓꣔꣕꣖꣗꣘꣙꤀꤁꤂꤃꤄꤅꤆꤇꤈꤉꧐꧑꧒꧓꧔꧕꧖꧗꧘꧙꧰꧱꧲꧳꧴꧵꧶꧷꧸꧹꩐꩑꩒꩓꩔꩕꩖�
 ��꩘꩙꯰꯱꯲꯳꯴꯵꯶꯷꯸꯹0123456789𐒠𐒡𐒢𐒣𐒤𐒥𐒦𐒧𐒨𐒩 =
+    1
+
+// Some characters are not supported while they are in the unicode category Nd.
+// val _𐴰 =
+//     1
+// val _𐴱 =
+//     1
+// val _𐴲 =
+//     1
+// val _𐴳 =
+//     1
+// val _𐴴 =
+//     1
+// val _𐴵 =
+//     1
+// val _𐴶 =
+//     1
+// val _𐴷 =
+//     1
+// val _𐴸 =
+//     1
+// val _𐴹 =
+//     1
+val _𑁦 =
+    1
+val _𑁧 =
+    1
+val _𑁨 =
+    1
+val _𑁩 =
+    1
+val _𑁪 =
+    1
+val _𑁫 =
+    1
+val _𑁬 =
+    1
+val _𑁭 =
+    1
+val _𑁮 =
+    1
+val _𑁯 =
+    1
+val _𑃰 =
+    1
+val _𑃱 =
+    1
+val _𑃲 =
+    1
+val _𑃳 =
+    1
+val _𑃴 =
+    1
+val _𑃵 =
+    1
+val _𑃶 =
+    1
+val _𑃷 =
+    1
+val _𑃸 =
+    1
+val _𑃹 =
+    1
+val _𑄶 =
+    1
+val _𑄷 =
+    1
+val _𑄸 =
+    1
+val _𑄹 =
+    1
+val _𑄺 =
+    1
+val _𑄻 =
+    1
+val _𑄼 =
+    1
+val _𑄽 =
+    1
+val _𑄾 =
+    1
+val _𑄿 =
+    1
+val _𑇐 =
+    1
+val _𑇑 =
+    1
+val _𑇒 =
+    1
+val _𑇓 =
+    1
+val _𑇔 =
+    1
+val _𑇕 =
+    1
+val _𑇖 =
+    1
+val _𑇗 =
+    1
+val _𑇘 =
+    1
+val _𑇙 =
+    1
+val _𑋰 =
+    1
+val _𑋱 =
+    1
+val _𑋲 =
+    1
+val _𑋳 =
+    1
+val _𑋴 =
+    1
+val _𑋵 =
+    1
+val _𑋶 =
+    1
+val _𑋷 =
+    1
+val _𑋸 =
+    1
+val _𑋹 =
+    1
+val _𑑐 =
+    1
+val _𑑑 =
+    1
+val _𑑒 =
+    1
+val _𑑓 =
+    1
+val _𑑔 =
+    1
+val _𑑕 =
+    1
+val _𑑖 =
+    1
+val _𑑗 =
+    1
+val _𑑘 =
+    1
+val _𑑙 =
+    1
+val _𑓐 =
+    1
+val _𑓑 =
+    1
+val _𑓒 =
+    1
+val _𑓓 =
+    1
+val _𑓔 =
+    1
+val _𑓕 =
+    1
+val _𑓖 =
+    1
+val _𑓗 =
+    1
+val _𑓘 =
+    1
+val _𑓙 =
+    1
+val _𑙐 =
+    1
+val _𑙑 =
+    1
+val _𑙒 =
+    1
+val _𑙓 =
+    1
+val _𑙔 =
+    1
+val _𑙕 =
+    1
+val _𑙖 =
+    1
+val _𑙗 =
+    1
+val _𑙘 =
+    1
+val _𑙙 =
+    1
+val _𑛀 =
+    1
+val _𑛁 =
+    1
+val _𑛂 =
+    1
+val _𑛃 =
+    1
+val _𑛄 =
+    1
+val _𑛅 =
+    1
+val _𑛆 =
+    1
+val _𑛇 =
+    1
+val _𑛈 =
+    1
+val _𑛉 =
+    1
+val _𑜰 =
+    1
+val _𑜱 =
+    1
+val _𑜲 =
+    1
+val _𑜳 =
+    1
+val _𑜴 =
+    1
+val _𑜵 =
+    1
+val _𑜶 =
+    1
+val _𑜷 =
+    1
+val _𑜸 =
+    1
+val _𑜹 =
+    1
+val _𑣠 =
+    1
+val _𑣡 =
+    1
+val _𑣢 =
+    1
+val _𑣣 =
+    1
+val _𑣤 =
+    1
+val _𑣥 =
+    1
+val _𑣦 =
+    1
+val _𑣧 =
+    1
+val _𑣨 =
+    1
+val _𑣩 =
+    1
+val _𑱐 =
+    1
+val _𑱑 =
+    1
+val _𑱒 =
+    1
+val _𑱓 =
+    1
+val _𑱔 =
+    1
+val _𑱕 =
+    1
+val _𑱖 =
+    1
+val _𑱗 =
+    1
+val _𑱘 =
+    1
+val _𑱙 =
+    1
+// val _𑵐 =
+//     1
+// val _𑵑 =
+//     1
+// val _𑵒 =
+//     1
+// val _𑵓 =
+//     1
+// val _𑵔 =
+//     1
+// val _𑵕 =
+//     1
+// val _𑵖 =
+//     1
+// val _𑵗 =
+//     1
+// val _𑵘 =
+//     1
+// val _𑵙 =
+//     1
+// val _𑶠 =
+//     1
+// val _𑶡 =
+//     1
+// val _𑶢 =
+//     1
+// val _𑶣 =
+//     1
+// val _𑶤 =
+//     1
+// val _𑶥 =
+//     1
+// val _𑶦 =
+//     1
+// val _𑶧 =
+//     1
+// val _𑶨 =
+//     1
+// val _𑶩 =
+//     1
+val _𖩠 =
+    1
+val _𖩡 =
+    1
+val _𖩢 =
+    1
+val _𖩣 =
+    1
+val _𖩤 =
+    1
+val _𖩥 =
+    1
+val _𖩦 =
+    1
+val _𖩧 =
+    1
+val _𖩨 =
+    1
+val _𖩩 =
+    1
+val _𖭐 =
+    1
+val _𖭑 =
+    1
+val _𖭒 =
+    1
+val _𖭓 =
+    1
+val _𖭔 =
+    1
+val _𖭕 =
+    1
+val _𖭖 =
+    1
+val _𖭗 =
+    1
+val _𖭘 =
+    1
+val _𖭙 =
+    1
+val _𝟎 =
+    1
+val _𝟏 =
+    1
+val _𝟐 =
+    1
+val _𝟑 =
+    1
+val _𝟒 =
+    1
+val _𝟓 =
+    1
+val _𝟔 =
+    1
+val _𝟕 =
+    1
+val _𝟖 =
+    1
+val _𝟗 =
+    1
+val _𝟘 =
+    1
+val _𝟙 =
+    1
+val _𝟚 =
+    1
+val _𝟛 =
+    1
+val _𝟜 =
+    1
+val _𝟝 =
+    1
+val _𝟞 =
+    1
+val _𝟟 =
+    1
+val _𝟠 =
+    1
+val _𝟡 =
+    1
+val _𝟢 =
+    1
+val _𝟣 =
+    1
+val _𝟤 =
+    1
+val _𝟥 =
+    1
+val _𝟦 =
+    1
+val _𝟧 =
+    1
+val _𝟨 =
+    1
+val _𝟩 =
+    1
+val _𝟪 =
+    1
+val _𝟫 =
+    1
+val _𝟬 =
+    1
+val _𝟭 =
+    1
+val _𝟮 =
+    1
+val _𝟯 =
+    1
+val _𝟰 =
+    1
+val _𝟱 =
+    1
+val _𝟲 =
+    1
+val _𝟳 =
+    1
+val _𝟴 =
+    1
+val _𝟵 =
+    1
+val _𝟶 =
+    1
+val _𝟷 =
+    1
+val _𝟸 =
+    1
+val _𝟹 =
+    1
+val _𝟺 =
+    1
+val _𝟻 =
+    1
+val _𝟼 =
+    1
+val _𝟽 =
+    1
+val _𝟾 =
+    1
+val _𝟿 =
+    1
+// val _𞅀 =
+//     1
+// val _𞅁 =
+//     1
+// val _𞅂 =
+//     1
+// val _𞅃 =
+//     1
+// val _𞅄 =
+//     1
+// val _𞅅 =
+//     1
+// val _𞅆 =
+//     1
+// val _𞅇 =
+//     1
+// val _𞅈 =
+//     1
+// val _𞅉 =
+//     1
+// val _𞋰 =
+//     1
+// val _𞋱 =
+//     1
+// val _𞋲 =
+//     1
+// val _𞋳 =
+//     1
+// val _𞋴 =
+//     1
+// val _𞋵 =
+//     1
+// val _𞋶 =
+//     1
+// val _𞋷 =
+//     1
+// val _𞋸 =
+//     1
+// val _𞋹 =
+//     1
+val _𞥐 =
+    1
+val _𞥑 =
+    1
+val _𞥒 =
+    1
+val _𞥓 =
+    1
+val _𞥔 =
+    1
+val _𞥕 =
+    1
+val _𞥖 =
+    1
+val _𞥗 =
+    1
+val _𞥘 =
+    1
+val _𞥙 =
+    1
+
+// UNICODE_CLASS_LL
+// UNICODE_CLASS_LM
+// UNICODE_CLASS_LO
+// UNICODE_CLASS_LT
+// UNICODE_CLASS_LU
+val aʰªDžA =
+    1
+
+// UNICODE_CLASS_NL (rejected for some reason)
+// val ᛮ =
+//     1
diff --git a/test/sample.kt b/test/sample.kt
index 7dd47b5eee..ddd5f28c62 100644
--- a/test/sample.kt
+++ b/test/sample.kt
@@ -56,8 +56,8 @@ fun main(args: Array<String>) {
 
 fun max(a: Int, b: Int): Int {
     if (a > b)
-        return a
-    else
+        return a // KNOWN_BUG
+    else // KNOWN_BUG
         return b
 }
 
@@ -83,16 +83,16 @@ fun getStringLength(obj: Any): Int? {
 
 fun main(args: Array<String>) {
     for (arg in args)
-        print(arg)
+        print(arg) // KNOWN_BUG
 }
 
 for (i in args.indices)
-    print(args[i])
+    print(args[i]) // KNOWN_BUG
 
-fun main(args: Array<String>) {
+fun main(args: Array<String>) { // KNOWN_BUG
     var i = 0
     while (i < args.size)
-        print(args[i++])
+        print(args[i++]) // KNOWN_BUG
 }
 
 fun cases(obj: Any) {
@@ -106,21 +106,21 @@ fun cases(obj: Any) {
 }
 
 if (x in 1..y-1)
-    print("OK")
+    print("OK") // KNOWN_BUG
 
-if (x !in 0..array.lastIndex)
-    print("Out")
+if (x !in 0..array.lastIndex) // KNOWN_BUG
+    print("Out") // KNOWN_BUG
 
-for (x in 1..5)
-    print(x)
+for (x in 1..5) // KNOWN_BUG
+    print(x) // KNOWN_BUG
 
-for (name in names)
-    println(name)
+for (name in names) // KNOWN_BUG
+    println(name) // KNOWN_BUG
 
-if (text in names) // names.contains(text) is called
-    print("Yes")
+if (text in names) // names.contains(text) is called // KNOWN_BUG
+    print("Yes") // KNOWN_BUG
 
-names.filter { it.startsWith("A") }
+names.filter { it.startsWith("A") } // KNOWN_BUG
     .sortedBy { it }
     .map { it.toUpperCase() }
     .forEach { print(it) }
@@ -227,7 +227,7 @@ inline fun <reified T: Any> Gson.fromJson(json): T = 
this.fromJson(json, T::clas
 loop@ for (i in 1..100) {
     for (j in 1..100) {
         if (x)
-            break@loop
+            break@loop // KNOWN_BUG
     }
 }
 
@@ -364,15 +364,15 @@ var stringRepresentation: String
     }
 
 var setterVisibility: String = "abc"
-    private set // the setter is private and has the default implementation
+    private set // the setter is private and has the default implementation  
// KNOWN_BUG
 
-var setterWithAnnotation: Any? = null
-@Inject set // annotate the setter with Inject
+var setterWithAnnotation: Any? = null // KNOWN_BUG
+    @Inject set // annotate the setter with Inject // KNOWN_BUG
 
-var counter = 0 // the initializer value is written directly to the backing 
field
+var counter = 0 // the initializer value is written directly to the backing 
field // KNOWN_BUG
     set(value) {
         if (value >= 0)
-            field = value
+            field = value // KNOWN_BUG
     }
 
 val isEmpty: Boolean
@@ -446,9 +446,9 @@ class D : A, B {
 private fun foo() {} // visible inside example.kt
 
 public var bar: Int = 5 // property is visible everywhere
-    private set         // setter is visible only in example.kt
+    private set         // setter is visible only in example.kt // KNOWN_BUG
 
-internal val baz = 6    // visible inside the same module
+internal val baz = 6    // visible inside the same module // KNOWN_BUG
 
 open class Outer {
     private val a = 1
@@ -555,12 +555,12 @@ fun <T : Comparable<T>> sort(list: List<T>) {
 }
 
 fun <T> cloneWhenGreater(list: List<T>, threshold: T): List<T>
-where T : Comparable,
-T : Cloneable {
-    return list.filter { it > threshold }.map { it.clone() }
-}
+    where T : Comparable,
+          T : Cloneable { // KNOWN_BUG
+    return list.filter { it > threshold }.map { it.clone() } // KNOWN_BUG
+} // KNOWN_BUG
 
-enum class Direction {
+enum class Direction { // KNOWN_BUG
     NORTH, SOUTH, WEST, EAST
 }
 
@@ -608,13 +608,12 @@ fun countClicks(window: JComponent) {
         object : MouseAdapter() {
             override fun mouseClicked(e: MouseEvent) {
                 clickCount++
-            }
+            } // KNOWN_BUG
 
             override fun mouseEntered(e: MouseEvent) {
                 enterCount++
-            }
-        }
-    )
+            } // KNOWN_BUG
+    })
     // ...
 }
 
@@ -652,8 +651,8 @@ infix fun Int.shl(x: Int): Int {
 fun <T> asList(vararg ts: T): List<T> {
     val result = ArrayList<T>()
     for (t in ts) // ts is an Array
-        result.add(t)
-    return result
+        result.add(t) // KNOWN_BUG
+    return result // KNOWN_BUG
 }
 
 tailrec fun findFixPoint(x: Double = 1.0): Double
@@ -674,8 +673,8 @@ val result = lock(lock, ::toBeSynchronized)
 fun <T, R> List<T>.map(transform: (T) -> R): List<R> {
     val result = arrayListOf<R>()
     for (item in this)
-        result.add(transform(item))
-    return result
+        result.add(transform(item)) // KNOWN_BUG
+    return result // KNOWN_BUG
 }
 
 val doubled = ints.map { it -> it * 2 }
@@ -688,9 +687,9 @@ max(strings, { a, b -> a.length < b.length
 fun <T> max(collection: Collection<T>, less: (T, T) -> Boolean): T? {
     var max: T? = null
     for (it in collection)
-        if (max == null || less(max, it))
-        max = it
-    return max
+        if (max == null || less(max, it)) // KNOWN_BUG
+            max = it // KNOWN_BUG
+    return max // KNOWN_BUG
 }
 
 val sum: (Int, Int) -> Int = { x, y -> x + y }



reply via email to

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