<NME> Comments.txt
<BEF> Elm File
  PsiComment(LINE_COMMENT)('-- this is a line comment')
  PsiWhiteSpace('\n')
  PsiWhiteSpace('\n')
  ElmValueDeclaration(VALUE_DECLARATION)
    ElmFunctionDeclarationLeft(FUNCTION_DECLARATION_LEFT)
      PsiElement(LOWER_CASE_IDENTIFIER)('n')
    PsiWhiteSpace(' ')
    PsiElement(EQ)('=')
    PsiWhiteSpace(' ')
    ElmExpression(EXPRESSION)
      ElmNumberConstant(NUMBER_CONSTANT)
        PsiElement(NUMBER_LITERAL)('42')
  PsiElement(VIRTUAL_END_DECL)(' ')
  PsiComment(LINE_COMMENT)('-- this is also a line comment')
  PsiWhiteSpace('\n')
  PsiWhiteSpace('\n')
  PsiWhiteSpace('\n')
  PsiComment(BLOCK_COMMENT)('{- this is a block comment.\nIt can span multiple lines\n-}')
  ElmValueDeclaration(VALUE_DECLARATION)
    ElmFunctionDeclarationLeft(FUNCTION_DECLARATION_LEFT)
      PsiElement(LOWER_CASE_IDENTIFIER)('foo')
    PsiWhiteSpace(' ')
    PsiElement(EQ)('=')
    PsiWhiteSpace(' ')
    ElmNumberConstantExpr(NUMBER_CONSTANT_EXPR)
      PsiElement(NUMBER_LITERAL)('42')
  PsiElement(VIRTUAL_END_DECL)('\n')
  PsiWhiteSpace('\n')
  PsiComment(BLOCK_COMMENT)('{- block comments can also be on a single line -}')
  PsiWhiteSpace('\n')
  ElmValueDeclaration(VALUE_DECLARATION)
    ElmFunctionDeclarationLeft(FUNCTION_DECLARATION_LEFT)
      PsiElement(LOWER_CASE_IDENTIFIER)('bar')
    PsiWhiteSpace(' ')
    PsiElement(EQ)('=')
    PsiWhiteSpace(' ')
    ElmNumberConstantExpr(NUMBER_CONSTANT_EXPR)
      PsiElement(NUMBER_LITERAL)('99')
  PsiElement(VIRTUAL_END_DECL)('\n')
  PsiWhiteSpace('\n')
  PsiComment(BLOCK_COMMENT)('{- block comments can be\n    {- nested -}\nlike this\n-}')
  PsiWhiteSpace('\n')
  ElmValueDeclaration(VALUE_DECLARATION)
    ElmFunctionDeclarationLeft(FUNCTION_DECLARATION_LEFT)
      PsiElement(LOWER_CASE_IDENTIFIER)('baz')
    PsiWhiteSpace(' ')
    PsiElement(EQ)('=')
    PsiWhiteSpace(' ')
    ElmNumberConstantExpr(NUMBER_CONSTANT_EXPR)
      PsiElement(NUMBER_LITERAL)('0')
  PsiElement(VIRTUAL_END_DECL)('\n')
  PsiWhiteSpace('\n')
  PsiWhiteSpace('\n')
  PsiComment(DOC_COMMENT)('{-| this is a doc comment.\nIt can span multiple lines\n-}')
  PsiWhiteSpace('\n')
  ElmValueDeclaration(VALUE_DECLARATION)
    ElmFunctionDeclarationLeft(FUNCTION_DECLARATION_LEFT)
      PsiElement(LOWER_CASE_IDENTIFIER)('foo2')
    PsiWhiteSpace(' ')
    PsiElement(EQ)('=')
    PsiWhiteSpace(' ')
    ElmNumberConstantExpr(NUMBER_CONSTANT_EXPR)
      PsiElement(NUMBER_LITERAL)('42')
  PsiElement(VIRTUAL_END_DECL)('\n')
  PsiWhiteSpace('\n')
  PsiComment(DOC_COMMENT)('{-| doc comments can also be on a single line -}')
  PsiWhiteSpace('\n')
  ElmValueDeclaration(VALUE_DECLARATION)
    ElmFunctionDeclarationLeft(FUNCTION_DECLARATION_LEFT)
      PsiElement(LOWER_CASE_IDENTIFIER)('bar2')
    PsiWhiteSpace(' ')
    PsiElement(EQ)('=')
    PsiWhiteSpace(' ')
    ElmNumberConstantExpr(NUMBER_CONSTANT_EXPR)
      PsiElement(NUMBER_LITERAL)('99')
  PsiElement(VIRTUAL_END_DECL)('\n')
  PsiWhiteSpace('\n')
  PsiComment(DOC_COMMENT)('{-| doc comments can contain block comments\n    {- nested -}\nand everything is still ok\n-}')
  PsiWhiteSpace('\n')
  ElmValueDeclaration(VALUE_DECLARATION)
    ElmFunctionDeclarationLeft(FUNCTION_DECLARATION_LEFT)
      PsiElement(LOWER_CASE_IDENTIFIER)('baz2')
    PsiWhiteSpace(' ')
    PsiElement(EQ)('=')
    PsiWhiteSpace(' ')
    ElmNumberConstantExpr(NUMBER_CONSTANT_EXPR)
      PsiElement(NUMBER_LITERAL)('0')

<MSG> Smarter insertion of virtual end decl tokens (#109)

Previously we were inserting them immediately after the last
code token, but if there was trailing whitespace or trailing
comment on that expression, that whitespace/comment would end
up AFTER the virtual end decl. Which is not desirable because
it logically belongs to the decl.

The Psi tree after this change is still not great in these
cases: the trailing whitespace is a _sibling_ of the value declaration.
But at least now it comes _before_ the virtual end decl.
<DFF> @@ -11,9 +11,9 @@ Elm File
     ElmExpression(EXPRESSION)
       ElmNumberConstant(NUMBER_CONSTANT)
         PsiElement(NUMBER_LITERAL)('42')
-  PsiElement(VIRTUAL_END_DECL)(' ')
+  PsiWhiteSpace(' ')
   PsiComment(LINE_COMMENT)('-- this is also a line comment')
-  PsiWhiteSpace('\n')
+  PsiElement(VIRTUAL_END_DECL)('\n')
   PsiWhiteSpace('\n')
   PsiWhiteSpace('\n')
   PsiComment(BLOCK_COMMENT)('{- this is a block comment.\nIt can span multiple lines\n-}')

Smarter insertion of virtual end decl tokens (#109)