Assign trailing and preceding whitespaces to lambda block until the last comment in parser
This commit is contained in:
@@ -17,13 +17,13 @@
|
||||
package org.jetbrains.kotlin.parsing
|
||||
|
||||
import com.intellij.lang.WhitespacesAndCommentsBinder
|
||||
import com.intellij.openapi.util.text.StringUtil
|
||||
import com.intellij.psi.tree.IElementType
|
||||
import org.jetbrains.kotlin.lexer.KtTokens
|
||||
import com.intellij.openapi.util.text.StringUtil
|
||||
|
||||
object PrecedingCommentsBinder : WhitespacesAndCommentsBinder {
|
||||
|
||||
override fun getEdgePosition(tokens: List<IElementType>, atStreamEdge: Boolean, getter: WhitespacesAndCommentsBinder.TokenTextGetter): Int {
|
||||
override fun getEdgePosition(
|
||||
tokens: List<IElementType>, atStreamEdge: Boolean, getter: WhitespacesAndCommentsBinder.TokenTextGetter): Int {
|
||||
if (tokens.isEmpty()) return 0
|
||||
|
||||
// 1. bind doc comment
|
||||
@@ -53,8 +53,8 @@ object PrecedingCommentsBinder : WhitespacesAndCommentsBinder {
|
||||
}
|
||||
|
||||
object PrecedingDocCommentsBinder : WhitespacesAndCommentsBinder {
|
||||
|
||||
override fun getEdgePosition(tokens: List<IElementType>, atStreamEdge: Boolean, getter: WhitespacesAndCommentsBinder.TokenTextGetter): Int {
|
||||
override fun getEdgePosition(
|
||||
tokens: List<IElementType>, atStreamEdge: Boolean, getter: WhitespacesAndCommentsBinder.TokenTextGetter): Int {
|
||||
if (tokens.isEmpty()) return 0
|
||||
|
||||
for (idx in tokens.indices.reversed()) {
|
||||
@@ -67,8 +67,8 @@ object PrecedingDocCommentsBinder : WhitespacesAndCommentsBinder {
|
||||
|
||||
// Binds comments on the same line
|
||||
object TrailingCommentsBinder : WhitespacesAndCommentsBinder {
|
||||
|
||||
override fun getEdgePosition(tokens: List<IElementType>, atStreamEdge: Boolean, getter: WhitespacesAndCommentsBinder.TokenTextGetter): Int {
|
||||
override fun getEdgePosition(
|
||||
tokens: List<IElementType>, atStreamEdge: Boolean, getter: WhitespacesAndCommentsBinder.TokenTextGetter): Int {
|
||||
if (tokens.isEmpty()) return 0
|
||||
|
||||
var result = 0
|
||||
@@ -87,8 +87,30 @@ object TrailingCommentsBinder : WhitespacesAndCommentsBinder {
|
||||
}
|
||||
}
|
||||
|
||||
private class AllCommentsBinder(val isTrailing: Boolean) : WhitespacesAndCommentsBinder {
|
||||
override fun getEdgePosition(
|
||||
tokens: List<IElementType>, atStreamEdge: Boolean, getter: WhitespacesAndCommentsBinder.TokenTextGetter): Int {
|
||||
if (tokens.isEmpty()) return 0
|
||||
|
||||
val size = tokens.size
|
||||
|
||||
// Skip comment if needed. Expect that there can't be several consecutive comments
|
||||
val endToken = tokens[if (isTrailing) size - 1 else 0]
|
||||
val shift = if (endToken == KtTokens.WHITE_SPACE) 1 else 0
|
||||
|
||||
return if (isTrailing) size - shift else shift
|
||||
}
|
||||
}
|
||||
|
||||
@JvmField
|
||||
val PRECEDING_ALL_COMMENTS_BINDER: WhitespacesAndCommentsBinder = AllCommentsBinder(false)
|
||||
|
||||
@JvmField
|
||||
val TRAILING_ALL_COMMENTS_BINDER: WhitespacesAndCommentsBinder = AllCommentsBinder(true)
|
||||
|
||||
object DoNotBindAnything : WhitespacesAndCommentsBinder {
|
||||
override fun getEdgePosition(tokens: List<IElementType>, atStreamEdge: Boolean, getter: WhitespacesAndCommentsBinder.TokenTextGetter): Int {
|
||||
override fun getEdgePosition(
|
||||
tokens: List<IElementType>, atStreamEdge: Boolean, getter: WhitespacesAndCommentsBinder.TokenTextGetter): Int {
|
||||
return 0
|
||||
}
|
||||
}
|
||||
@@ -1091,7 +1091,9 @@ public class KotlinExpressionParsing extends AbstractKotlinParsing {
|
||||
else {
|
||||
PsiBuilder.Marker body = mark();
|
||||
parseStatements();
|
||||
|
||||
body.done(BLOCK);
|
||||
body.setCustomEdgeTokenBinders(CommentBindersKt.PRECEDING_ALL_COMMENTS_BINDER, CommentBindersKt.TRAILING_ALL_COMMENTS_BINDER);
|
||||
|
||||
expect(RBRACE, "Expecting '}'");
|
||||
literal.done(FUNCTION_LITERAL);
|
||||
|
||||
+21
-21
@@ -305,30 +305,30 @@ sink:
|
||||
}
|
||||
---------------------
|
||||
L3:
|
||||
2 <START> INIT: in: {some=D} out: {some=D}
|
||||
3 mark(if (state) state = true println(state))
|
||||
2 <START> INIT: in: {some=D} out: {some=D}
|
||||
3 mark(if (state) state = true println(state) // OK)
|
||||
mark(if (state) state = true)
|
||||
magic[IMPLICIT_RECEIVER](state) -> <v0>
|
||||
r(state|<v0>) -> <v1>
|
||||
jf(L5|<v1>) USE: in: {state=READ} out: {state=READ}
|
||||
jf(L5|<v1>) USE: in: {state=READ} out: {state=READ}
|
||||
magic[IMPLICIT_RECEIVER](state) -> <v2>
|
||||
r(true) -> <v3> USE: in: {state=WRITTEN_AFTER_READ} out: {state=WRITTEN_AFTER_READ}
|
||||
w(state|<v2>, <v3>) USE: in: {state=READ} out: {state=WRITTEN_AFTER_READ}
|
||||
r(true) -> <v3> USE: in: {state=WRITTEN_AFTER_READ} out: {state=WRITTEN_AFTER_READ}
|
||||
w(state|<v2>, <v3>) USE: in: {state=READ} out: {state=WRITTEN_AFTER_READ}
|
||||
jmp(L6)
|
||||
L5 [else branch]:
|
||||
read (Unit)
|
||||
L6 ['if' expression result]:
|
||||
merge(if (state) state = true|!<v4>) -> <v5>
|
||||
magic[IMPLICIT_RECEIVER](state) -> <v6> USE: in: {state=READ} out: {state=READ}
|
||||
r(state|<v6>) -> <v7> USE: in: {} out: {state=READ}
|
||||
magic[IMPLICIT_RECEIVER](state) -> <v6> USE: in: {state=READ} out: {state=READ}
|
||||
r(state|<v6>) -> <v7> USE: in: {} out: {state=READ}
|
||||
mark(println(state))
|
||||
call(println(state), println|<v7>) -> <v8>
|
||||
L4:
|
||||
2 <END>
|
||||
error:
|
||||
<ERROR> INIT: in: {} out: {}
|
||||
<ERROR> INIT: in: {} out: {}
|
||||
sink:
|
||||
<SINK> INIT: in: {some=I?} out: {some=I?} USE: in: {} out: {}
|
||||
<SINK> INIT: in: {some=I?} out: {some=I?} USE: in: {} out: {}
|
||||
=====================
|
||||
== exec ==
|
||||
fun <T> exec(f: () -> T): T = f()
|
||||
@@ -391,30 +391,30 @@ sink:
|
||||
}
|
||||
---------------------
|
||||
L3:
|
||||
2 <START> INIT: in: {some=D} out: {some=D}
|
||||
3 mark(if (state) state = true println(state))
|
||||
2 <START> INIT: in: {some=D} out: {some=D}
|
||||
3 mark(if (state) state = true println(state) // must be initialized)
|
||||
mark(if (state) state = true)
|
||||
magic[IMPLICIT_RECEIVER](state) -> <v0>
|
||||
r(state|<v0>) -> <v1>
|
||||
jf(L5|<v1>) USE: in: {state=READ} out: {state=READ}
|
||||
jf(L5|<v1>) USE: in: {state=READ} out: {state=READ}
|
||||
magic[IMPLICIT_RECEIVER](state) -> <v2>
|
||||
r(true) -> <v3> USE: in: {state=WRITTEN_AFTER_READ} out: {state=WRITTEN_AFTER_READ}
|
||||
w(state|<v2>, <v3>) INIT: in: {some=D} out: {some=D, state=I} USE: in: {state=READ} out: {state=WRITTEN_AFTER_READ}
|
||||
jmp(L6) INIT: in: {some=D, state=I} out: {some=D, state=I}
|
||||
r(true) -> <v3> USE: in: {state=WRITTEN_AFTER_READ} out: {state=WRITTEN_AFTER_READ}
|
||||
w(state|<v2>, <v3>) INIT: in: {some=D} out: {some=D, state=I} USE: in: {state=READ} out: {state=WRITTEN_AFTER_READ}
|
||||
jmp(L6) INIT: in: {some=D, state=I} out: {some=D, state=I}
|
||||
L5 [else branch]:
|
||||
read (Unit) INIT: in: {some=D} out: {some=D}
|
||||
read (Unit) INIT: in: {some=D} out: {some=D}
|
||||
L6 ['if' expression result]:
|
||||
merge(if (state) state = true|!<v4>) -> <v5> INIT: in: {some=D, state=I} out: {some=D, state=I}
|
||||
magic[IMPLICIT_RECEIVER](state) -> <v6> USE: in: {state=READ} out: {state=READ}
|
||||
r(state|<v6>) -> <v7> USE: in: {} out: {state=READ}
|
||||
merge(if (state) state = true|!<v4>) -> <v5> INIT: in: {some=D, state=I} out: {some=D, state=I}
|
||||
magic[IMPLICIT_RECEIVER](state) -> <v6> USE: in: {state=READ} out: {state=READ}
|
||||
r(state|<v6>) -> <v7> USE: in: {} out: {state=READ}
|
||||
mark(println(state))
|
||||
call(println(state), println|<v7>) -> <v8>
|
||||
L4:
|
||||
2 <END>
|
||||
error:
|
||||
<ERROR> INIT: in: {} out: {}
|
||||
<ERROR> INIT: in: {} out: {}
|
||||
sink:
|
||||
<SINK> INIT: in: {some=I?, state=I} out: {some=I?, state=I} USE: in: {} out: {}
|
||||
<SINK> INIT: in: {some=I?, state=I} out: {some=I?, state=I} USE: in: {} out: {}
|
||||
=====================
|
||||
== Demo5 ==
|
||||
class Demo5 {
|
||||
|
||||
@@ -164,16 +164,16 @@ true <v3>: Boolean
|
||||
println(state) // OK
|
||||
}
|
||||
---------------------
|
||||
<v0>: Demo3 NEW: magic[IMPLICIT_RECEIVER](state) -> <v0>
|
||||
<v2>: Demo3 NEW: magic[IMPLICIT_RECEIVER](state) -> <v2>
|
||||
<v6>: Demo3 NEW: magic[IMPLICIT_RECEIVER](state) -> <v6>
|
||||
state <v1>: Boolean NEW: r(state|<v0>) -> <v1>
|
||||
true <v3>: Boolean NEW: r(true) -> <v3>
|
||||
state = true !<v4>: *
|
||||
if (state) state = true <v5>: * NEW: merge(if (state) state = true|!<v4>) -> <v5>
|
||||
state <v7>: * NEW: r(state|<v6>) -> <v7>
|
||||
println(state) <v8>: * NEW: call(println(state), println|<v7>) -> <v8>
|
||||
if (state) state = true println(state) <v8>: * COPY
|
||||
<v0>: Demo3 NEW: magic[IMPLICIT_RECEIVER](state) -> <v0>
|
||||
<v2>: Demo3 NEW: magic[IMPLICIT_RECEIVER](state) -> <v2>
|
||||
<v6>: Demo3 NEW: magic[IMPLICIT_RECEIVER](state) -> <v6>
|
||||
state <v1>: Boolean NEW: r(state|<v0>) -> <v1>
|
||||
true <v3>: Boolean NEW: r(true) -> <v3>
|
||||
state = true !<v4>: *
|
||||
if (state) state = true <v5>: * NEW: merge(if (state) state = true|!<v4>) -> <v5>
|
||||
state <v7>: * NEW: r(state|<v6>) -> <v7>
|
||||
println(state) <v8>: * NEW: call(println(state), println|<v7>) -> <v8>
|
||||
if (state) state = true println(state) // OK <v8>: * COPY
|
||||
=====================
|
||||
== exec ==
|
||||
fun <T> exec(f: () -> T): T = f()
|
||||
@@ -206,16 +206,16 @@ true <v2>: B
|
||||
println(state) // must be initialized
|
||||
}
|
||||
---------------------
|
||||
<v0>: Demo4 NEW: magic[IMPLICIT_RECEIVER](state) -> <v0>
|
||||
<v2>: Demo4 NEW: magic[IMPLICIT_RECEIVER](state) -> <v2>
|
||||
<v6>: Demo4 NEW: magic[IMPLICIT_RECEIVER](state) -> <v6>
|
||||
state <v1>: Boolean NEW: r(state|<v0>) -> <v1>
|
||||
true <v3>: Boolean NEW: r(true) -> <v3>
|
||||
state = true !<v4>: *
|
||||
if (state) state = true <v5>: * NEW: merge(if (state) state = true|!<v4>) -> <v5>
|
||||
state <v7>: * NEW: r(state|<v6>) -> <v7>
|
||||
println(state) <v8>: * NEW: call(println(state), println|<v7>) -> <v8>
|
||||
if (state) state = true println(state) <v8>: * COPY
|
||||
<v0>: Demo4 NEW: magic[IMPLICIT_RECEIVER](state) -> <v0>
|
||||
<v2>: Demo4 NEW: magic[IMPLICIT_RECEIVER](state) -> <v2>
|
||||
<v6>: Demo4 NEW: magic[IMPLICIT_RECEIVER](state) -> <v6>
|
||||
state <v1>: Boolean NEW: r(state|<v0>) -> <v1>
|
||||
true <v3>: Boolean NEW: r(true) -> <v3>
|
||||
state = true !<v4>: *
|
||||
if (state) state = true <v5>: * NEW: merge(if (state) state = true|!<v4>) -> <v5>
|
||||
state <v7>: * NEW: r(state|<v6>) -> <v7>
|
||||
println(state) <v8>: * NEW: call(println(state), println|<v7>) -> <v8>
|
||||
if (state) state = true println(state) // must be initialized <v8>: * COPY
|
||||
=====================
|
||||
== Demo5 ==
|
||||
class Demo5 {
|
||||
|
||||
@@ -58,15 +58,15 @@ sink:
|
||||
---------------------
|
||||
L3:
|
||||
3 <START>
|
||||
4 mark(return nonLocal)
|
||||
4 mark(return nonLocal //unreachable)
|
||||
r(nonLocal) -> <v0>
|
||||
ret(*|<v0>) L1 NEXT:[<END>]
|
||||
ret(*|<v0>) L1 NEXT:[<END>]
|
||||
L4:
|
||||
3 <END> NEXT:[<SINK>] PREV:[]
|
||||
3 <END> NEXT:[<SINK>] PREV:[]
|
||||
error:
|
||||
<ERROR> PREV:[]
|
||||
<ERROR> PREV:[]
|
||||
sink:
|
||||
<SINK> PREV:[<ERROR>, <END>]
|
||||
<SINK> PREV:[<ERROR>, <END>]
|
||||
=====================
|
||||
== doSomething ==
|
||||
fun doSomething() {}
|
||||
|
||||
+3
-3
@@ -26,9 +26,9 @@ return "NON_LOCAL_FAILED $localResult"
|
||||
return nonLocal //unreachable
|
||||
}
|
||||
---------------------
|
||||
nonLocal <v0>: String NEW: r(nonLocal) -> <v0>
|
||||
return nonLocal !<v1>: *
|
||||
return nonLocal !<v1>: * COPY
|
||||
nonLocal <v0>: String NEW: r(nonLocal) -> <v0>
|
||||
return nonLocal !<v1>: *
|
||||
return nonLocal //unreachable !<v1>: * COPY
|
||||
=====================
|
||||
== doSomething ==
|
||||
fun doSomething() {}
|
||||
|
||||
@@ -0,0 +1,38 @@
|
||||
val la1 = {
|
||||
// start
|
||||
// start 1
|
||||
foo()
|
||||
|
||||
// middle
|
||||
|
||||
foo()
|
||||
|
||||
// end
|
||||
}
|
||||
|
||||
val la2 = {
|
||||
/**/
|
||||
}
|
||||
|
||||
val la3 = {
|
||||
/** */
|
||||
}
|
||||
|
||||
val la4 = {
|
||||
/** Should be under block */
|
||||
|
||||
/** Should be under property */
|
||||
val some = 1
|
||||
}
|
||||
|
||||
val la5 = {
|
||||
/** */
|
||||
/** */
|
||||
}
|
||||
|
||||
val la6 = /*1*/ {/*2*/ a /*3*/ -> /*4*/
|
||||
}
|
||||
|
||||
val la7 = {/**/}
|
||||
|
||||
fun foo() {}
|
||||
+191
@@ -0,0 +1,191 @@
|
||||
JetFile: CommentsBindingInLambda.kt
|
||||
PACKAGE_DIRECTIVE
|
||||
<empty list>
|
||||
IMPORT_LIST
|
||||
<empty list>
|
||||
PROPERTY
|
||||
PsiElement(val)('val')
|
||||
PsiWhiteSpace(' ')
|
||||
PsiElement(IDENTIFIER)('la1')
|
||||
PsiWhiteSpace(' ')
|
||||
PsiElement(EQ)('=')
|
||||
PsiWhiteSpace(' ')
|
||||
LAMBDA_EXPRESSION
|
||||
FUNCTION_LITERAL
|
||||
PsiElement(LBRACE)('{')
|
||||
PsiWhiteSpace('\n ')
|
||||
BLOCK
|
||||
PsiComment(EOL_COMMENT)('// start')
|
||||
PsiWhiteSpace('\n ')
|
||||
PsiComment(EOL_COMMENT)('// start 1')
|
||||
PsiWhiteSpace('\n ')
|
||||
CALL_EXPRESSION
|
||||
REFERENCE_EXPRESSION
|
||||
PsiElement(IDENTIFIER)('foo')
|
||||
VALUE_ARGUMENT_LIST
|
||||
PsiElement(LPAR)('(')
|
||||
PsiElement(RPAR)(')')
|
||||
PsiWhiteSpace('\n\n ')
|
||||
PsiComment(EOL_COMMENT)('// middle')
|
||||
PsiWhiteSpace('\n\n ')
|
||||
CALL_EXPRESSION
|
||||
REFERENCE_EXPRESSION
|
||||
PsiElement(IDENTIFIER)('foo')
|
||||
VALUE_ARGUMENT_LIST
|
||||
PsiElement(LPAR)('(')
|
||||
PsiElement(RPAR)(')')
|
||||
PsiWhiteSpace('\n\n ')
|
||||
PsiComment(EOL_COMMENT)('// end')
|
||||
PsiWhiteSpace('\n')
|
||||
PsiElement(RBRACE)('}')
|
||||
PsiWhiteSpace('\n\n')
|
||||
PROPERTY
|
||||
PsiElement(val)('val')
|
||||
PsiWhiteSpace(' ')
|
||||
PsiElement(IDENTIFIER)('la2')
|
||||
PsiWhiteSpace(' ')
|
||||
PsiElement(EQ)('=')
|
||||
PsiWhiteSpace(' ')
|
||||
LAMBDA_EXPRESSION
|
||||
FUNCTION_LITERAL
|
||||
PsiElement(LBRACE)('{')
|
||||
PsiWhiteSpace('\n ')
|
||||
BLOCK
|
||||
PsiComment(BLOCK_COMMENT)('/**/')
|
||||
PsiWhiteSpace('\n')
|
||||
PsiElement(RBRACE)('}')
|
||||
PsiWhiteSpace('\n\n')
|
||||
PROPERTY
|
||||
PsiElement(val)('val')
|
||||
PsiWhiteSpace(' ')
|
||||
PsiElement(IDENTIFIER)('la3')
|
||||
PsiWhiteSpace(' ')
|
||||
PsiElement(EQ)('=')
|
||||
PsiWhiteSpace(' ')
|
||||
LAMBDA_EXPRESSION
|
||||
FUNCTION_LITERAL
|
||||
PsiElement(LBRACE)('{')
|
||||
PsiWhiteSpace('\n ')
|
||||
BLOCK
|
||||
KDoc
|
||||
PsiElement(KDOC_START)('/**')
|
||||
KDOC_SECTION
|
||||
PsiElement(KDOC_TEXT)(' ')
|
||||
PsiElement(KDOC_END)('*/')
|
||||
PsiWhiteSpace('\n')
|
||||
PsiElement(RBRACE)('}')
|
||||
PsiWhiteSpace('\n\n')
|
||||
PROPERTY
|
||||
PsiElement(val)('val')
|
||||
PsiWhiteSpace(' ')
|
||||
PsiElement(IDENTIFIER)('la4')
|
||||
PsiWhiteSpace(' ')
|
||||
PsiElement(EQ)('=')
|
||||
PsiWhiteSpace(' ')
|
||||
LAMBDA_EXPRESSION
|
||||
FUNCTION_LITERAL
|
||||
PsiElement(LBRACE)('{')
|
||||
PsiWhiteSpace('\n ')
|
||||
BLOCK
|
||||
KDoc
|
||||
PsiElement(KDOC_START)('/**')
|
||||
KDOC_SECTION
|
||||
PsiElement(KDOC_TEXT)(' Should be under block ')
|
||||
PsiElement(KDOC_END)('*/')
|
||||
PsiWhiteSpace('\n\n ')
|
||||
PROPERTY
|
||||
KDoc
|
||||
PsiElement(KDOC_START)('/**')
|
||||
KDOC_SECTION
|
||||
PsiElement(KDOC_TEXT)(' Should be under property ')
|
||||
PsiElement(KDOC_END)('*/')
|
||||
PsiWhiteSpace('\n ')
|
||||
PsiElement(val)('val')
|
||||
PsiWhiteSpace(' ')
|
||||
PsiElement(IDENTIFIER)('some')
|
||||
PsiWhiteSpace(' ')
|
||||
PsiElement(EQ)('=')
|
||||
PsiWhiteSpace(' ')
|
||||
INTEGER_CONSTANT
|
||||
PsiElement(INTEGER_LITERAL)('1')
|
||||
PsiWhiteSpace('\n')
|
||||
PsiElement(RBRACE)('}')
|
||||
PsiWhiteSpace('\n\n')
|
||||
PROPERTY
|
||||
PsiElement(val)('val')
|
||||
PsiWhiteSpace(' ')
|
||||
PsiElement(IDENTIFIER)('la5')
|
||||
PsiWhiteSpace(' ')
|
||||
PsiElement(EQ)('=')
|
||||
PsiWhiteSpace(' ')
|
||||
LAMBDA_EXPRESSION
|
||||
FUNCTION_LITERAL
|
||||
PsiElement(LBRACE)('{')
|
||||
PsiWhiteSpace('\n ')
|
||||
BLOCK
|
||||
KDoc
|
||||
PsiElement(KDOC_START)('/**')
|
||||
KDOC_SECTION
|
||||
PsiElement(KDOC_TEXT)(' ')
|
||||
PsiElement(KDOC_END)('*/')
|
||||
PsiWhiteSpace('\n ')
|
||||
KDoc
|
||||
PsiElement(KDOC_START)('/**')
|
||||
KDOC_SECTION
|
||||
PsiElement(KDOC_TEXT)(' ')
|
||||
PsiElement(KDOC_END)('*/')
|
||||
PsiWhiteSpace('\n')
|
||||
PsiElement(RBRACE)('}')
|
||||
PsiWhiteSpace('\n\n')
|
||||
PROPERTY
|
||||
PsiElement(val)('val')
|
||||
PsiWhiteSpace(' ')
|
||||
PsiElement(IDENTIFIER)('la6')
|
||||
PsiWhiteSpace(' ')
|
||||
PsiElement(EQ)('=')
|
||||
PsiWhiteSpace(' ')
|
||||
PsiComment(BLOCK_COMMENT)('/*1*/')
|
||||
PsiWhiteSpace(' ')
|
||||
LAMBDA_EXPRESSION
|
||||
FUNCTION_LITERAL
|
||||
PsiElement(LBRACE)('{')
|
||||
PsiComment(BLOCK_COMMENT)('/*2*/')
|
||||
PsiWhiteSpace(' ')
|
||||
VALUE_PARAMETER_LIST
|
||||
VALUE_PARAMETER
|
||||
PsiElement(IDENTIFIER)('a')
|
||||
PsiWhiteSpace(' ')
|
||||
PsiComment(BLOCK_COMMENT)('/*3*/')
|
||||
PsiWhiteSpace(' ')
|
||||
PsiElement(ARROW)('->')
|
||||
PsiWhiteSpace(' ')
|
||||
BLOCK
|
||||
PsiComment(BLOCK_COMMENT)('/*4*/')
|
||||
PsiWhiteSpace('\n')
|
||||
PsiElement(RBRACE)('}')
|
||||
PsiWhiteSpace('\n\n')
|
||||
PROPERTY
|
||||
PsiElement(val)('val')
|
||||
PsiWhiteSpace(' ')
|
||||
PsiElement(IDENTIFIER)('la7')
|
||||
PsiWhiteSpace(' ')
|
||||
PsiElement(EQ)('=')
|
||||
PsiWhiteSpace(' ')
|
||||
LAMBDA_EXPRESSION
|
||||
FUNCTION_LITERAL
|
||||
PsiElement(LBRACE)('{')
|
||||
BLOCK
|
||||
PsiComment(BLOCK_COMMENT)('/**/')
|
||||
PsiElement(RBRACE)('}')
|
||||
PsiWhiteSpace('\n\n')
|
||||
FUN
|
||||
PsiElement(fun)('fun')
|
||||
PsiWhiteSpace(' ')
|
||||
PsiElement(IDENTIFIER)('foo')
|
||||
VALUE_PARAMETER_LIST
|
||||
PsiElement(LPAR)('(')
|
||||
PsiElement(RPAR)(')')
|
||||
PsiWhiteSpace(' ')
|
||||
BLOCK
|
||||
PsiElement(LBRACE)('{')
|
||||
PsiElement(RBRACE)('}')
|
||||
@@ -0,0 +1,21 @@
|
||||
fun test() {
|
||||
if (true) {/*start-end*/}
|
||||
|
||||
if (true) {
|
||||
/*start-end*/
|
||||
}
|
||||
|
||||
if (true) {
|
||||
/*start*/
|
||||
/*end*/
|
||||
}
|
||||
|
||||
if (true) {
|
||||
/*start*/
|
||||
|
||||
/** doc */
|
||||
val a = 12
|
||||
|
||||
/*end*/
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,103 @@
|
||||
JetFile: CommentsBindingInStatementBlock.kt
|
||||
PACKAGE_DIRECTIVE
|
||||
<empty list>
|
||||
IMPORT_LIST
|
||||
<empty list>
|
||||
FUN
|
||||
PsiElement(fun)('fun')
|
||||
PsiWhiteSpace(' ')
|
||||
PsiElement(IDENTIFIER)('test')
|
||||
VALUE_PARAMETER_LIST
|
||||
PsiElement(LPAR)('(')
|
||||
PsiElement(RPAR)(')')
|
||||
PsiWhiteSpace(' ')
|
||||
BLOCK
|
||||
PsiElement(LBRACE)('{')
|
||||
PsiWhiteSpace('\n ')
|
||||
IF
|
||||
PsiElement(if)('if')
|
||||
PsiWhiteSpace(' ')
|
||||
PsiElement(LPAR)('(')
|
||||
CONDITION
|
||||
BOOLEAN_CONSTANT
|
||||
PsiElement(true)('true')
|
||||
PsiElement(RPAR)(')')
|
||||
PsiWhiteSpace(' ')
|
||||
THEN
|
||||
BLOCK
|
||||
PsiElement(LBRACE)('{')
|
||||
PsiComment(BLOCK_COMMENT)('/*start-end*/')
|
||||
PsiElement(RBRACE)('}')
|
||||
PsiWhiteSpace('\n\n ')
|
||||
IF
|
||||
PsiElement(if)('if')
|
||||
PsiWhiteSpace(' ')
|
||||
PsiElement(LPAR)('(')
|
||||
CONDITION
|
||||
BOOLEAN_CONSTANT
|
||||
PsiElement(true)('true')
|
||||
PsiElement(RPAR)(')')
|
||||
PsiWhiteSpace(' ')
|
||||
THEN
|
||||
BLOCK
|
||||
PsiElement(LBRACE)('{')
|
||||
PsiWhiteSpace('\n ')
|
||||
PsiComment(BLOCK_COMMENT)('/*start-end*/')
|
||||
PsiWhiteSpace('\n ')
|
||||
PsiElement(RBRACE)('}')
|
||||
PsiWhiteSpace('\n\n ')
|
||||
IF
|
||||
PsiElement(if)('if')
|
||||
PsiWhiteSpace(' ')
|
||||
PsiElement(LPAR)('(')
|
||||
CONDITION
|
||||
BOOLEAN_CONSTANT
|
||||
PsiElement(true)('true')
|
||||
PsiElement(RPAR)(')')
|
||||
PsiWhiteSpace(' ')
|
||||
THEN
|
||||
BLOCK
|
||||
PsiElement(LBRACE)('{')
|
||||
PsiWhiteSpace('\n ')
|
||||
PsiComment(BLOCK_COMMENT)('/*start*/')
|
||||
PsiWhiteSpace('\n ')
|
||||
PsiComment(BLOCK_COMMENT)('/*end*/')
|
||||
PsiWhiteSpace('\n ')
|
||||
PsiElement(RBRACE)('}')
|
||||
PsiWhiteSpace('\n\n ')
|
||||
IF
|
||||
PsiElement(if)('if')
|
||||
PsiWhiteSpace(' ')
|
||||
PsiElement(LPAR)('(')
|
||||
CONDITION
|
||||
BOOLEAN_CONSTANT
|
||||
PsiElement(true)('true')
|
||||
PsiElement(RPAR)(')')
|
||||
PsiWhiteSpace(' ')
|
||||
THEN
|
||||
BLOCK
|
||||
PsiElement(LBRACE)('{')
|
||||
PsiWhiteSpace('\n ')
|
||||
PsiComment(BLOCK_COMMENT)('/*start*/')
|
||||
PsiWhiteSpace('\n\n ')
|
||||
PROPERTY
|
||||
KDoc
|
||||
PsiElement(KDOC_START)('/**')
|
||||
KDOC_SECTION
|
||||
PsiElement(KDOC_TEXT)(' doc ')
|
||||
PsiElement(KDOC_END)('*/')
|
||||
PsiWhiteSpace('\n ')
|
||||
PsiElement(val)('val')
|
||||
PsiWhiteSpace(' ')
|
||||
PsiElement(IDENTIFIER)('a')
|
||||
PsiWhiteSpace(' ')
|
||||
PsiElement(EQ)('=')
|
||||
PsiWhiteSpace(' ')
|
||||
INTEGER_CONSTANT
|
||||
PsiElement(INTEGER_LITERAL)('12')
|
||||
PsiWhiteSpace('\n\n ')
|
||||
PsiComment(BLOCK_COMMENT)('/*end*/')
|
||||
PsiWhiteSpace('\n ')
|
||||
PsiElement(RBRACE)('}')
|
||||
PsiWhiteSpace('\n')
|
||||
PsiElement(RBRACE)('}')
|
||||
+12
@@ -0,0 +1,12 @@
|
||||
fun test() {
|
||||
// start
|
||||
foo()
|
||||
|
||||
// middle
|
||||
|
||||
foo()
|
||||
|
||||
// end
|
||||
}
|
||||
|
||||
fun foo() {}
|
||||
+49
@@ -0,0 +1,49 @@
|
||||
JetFile: LineCommentsInBlock.kt
|
||||
PACKAGE_DIRECTIVE
|
||||
<empty list>
|
||||
IMPORT_LIST
|
||||
<empty list>
|
||||
FUN
|
||||
PsiElement(fun)('fun')
|
||||
PsiWhiteSpace(' ')
|
||||
PsiElement(IDENTIFIER)('test')
|
||||
VALUE_PARAMETER_LIST
|
||||
PsiElement(LPAR)('(')
|
||||
PsiElement(RPAR)(')')
|
||||
PsiWhiteSpace(' ')
|
||||
BLOCK
|
||||
PsiElement(LBRACE)('{')
|
||||
PsiWhiteSpace('\n ')
|
||||
PsiComment(EOL_COMMENT)('// start')
|
||||
PsiWhiteSpace('\n ')
|
||||
CALL_EXPRESSION
|
||||
REFERENCE_EXPRESSION
|
||||
PsiElement(IDENTIFIER)('foo')
|
||||
VALUE_ARGUMENT_LIST
|
||||
PsiElement(LPAR)('(')
|
||||
PsiElement(RPAR)(')')
|
||||
PsiWhiteSpace('\n\n ')
|
||||
PsiComment(EOL_COMMENT)('// middle')
|
||||
PsiWhiteSpace('\n\n ')
|
||||
CALL_EXPRESSION
|
||||
REFERENCE_EXPRESSION
|
||||
PsiElement(IDENTIFIER)('foo')
|
||||
VALUE_ARGUMENT_LIST
|
||||
PsiElement(LPAR)('(')
|
||||
PsiElement(RPAR)(')')
|
||||
PsiWhiteSpace('\n\n ')
|
||||
PsiComment(EOL_COMMENT)('// end')
|
||||
PsiWhiteSpace('\n')
|
||||
PsiElement(RBRACE)('}')
|
||||
PsiWhiteSpace('\n\n')
|
||||
FUN
|
||||
PsiElement(fun)('fun')
|
||||
PsiWhiteSpace(' ')
|
||||
PsiElement(IDENTIFIER)('foo')
|
||||
VALUE_PARAMETER_LIST
|
||||
PsiElement(LPAR)('(')
|
||||
PsiElement(RPAR)(')')
|
||||
PsiWhiteSpace(' ')
|
||||
BLOCK
|
||||
PsiElement(LBRACE)('{')
|
||||
PsiElement(RBRACE)('}')
|
||||
+2
-2
@@ -61,9 +61,9 @@ JetFile: lambda.kt
|
||||
FUNCTION_LITERAL
|
||||
PsiElement(LBRACE)('{')
|
||||
PsiWhiteSpace(' ')
|
||||
PsiComment(EOL_COMMENT)('// parsed as array access')
|
||||
PsiWhiteSpace('\n ')
|
||||
BLOCK
|
||||
PsiComment(EOL_COMMENT)('// parsed as array access')
|
||||
PsiWhiteSpace('\n ')
|
||||
CALL_EXPRESSION
|
||||
REFERENCE_EXPRESSION
|
||||
PsiElement(IDENTIFIER)('print')
|
||||
|
||||
+6
-6
@@ -33,9 +33,9 @@ JetFile: recovery.kt
|
||||
FUNCTION_LITERAL
|
||||
PsiElement(LBRACE)('{')
|
||||
PsiWhiteSpace(' ')
|
||||
PsiComment(EOL_COMMENT)('// should be no space after c')
|
||||
PsiWhiteSpace('\n ')
|
||||
BLOCK
|
||||
PsiComment(EOL_COMMENT)('// should be no space after c')
|
||||
PsiWhiteSpace('\n ')
|
||||
RETURN
|
||||
PsiElement(return)('return')
|
||||
PsiWhiteSpace(' ')
|
||||
@@ -61,9 +61,9 @@ JetFile: recovery.kt
|
||||
FUNCTION_LITERAL
|
||||
PsiElement(LBRACE)('{')
|
||||
PsiWhiteSpace(' ')
|
||||
PsiComment(EOL_COMMENT)('// no label identifier')
|
||||
PsiWhiteSpace('\n ')
|
||||
BLOCK
|
||||
PsiComment(EOL_COMMENT)('// no label identifier')
|
||||
PsiWhiteSpace('\n ')
|
||||
RETURN
|
||||
PsiElement(return)('return')
|
||||
PsiWhiteSpace(' ')
|
||||
@@ -94,9 +94,9 @@ JetFile: recovery.kt
|
||||
FUNCTION_LITERAL
|
||||
PsiElement(LBRACE)('{')
|
||||
PsiWhiteSpace(' ')
|
||||
PsiComment(EOL_COMMENT)('// should be no space after loop2')
|
||||
PsiWhiteSpace('\n ')
|
||||
BLOCK
|
||||
PsiComment(EOL_COMMENT)('// should be no space after loop2')
|
||||
PsiWhiteSpace('\n ')
|
||||
RETURN
|
||||
PsiElement(return)('return')
|
||||
PsiErrorElement:Label must be named
|
||||
|
||||
@@ -127,6 +127,18 @@ public class ParsingTestGenerated extends AbstractParsingTest {
|
||||
doParsingTest(fileName);
|
||||
}
|
||||
|
||||
@TestMetadata("CommentsBindingInLambda.kt")
|
||||
public void testCommentsBindingInLambda() throws Exception {
|
||||
String fileName = KotlinTestUtils.navigationMetadata("compiler/testData/psi/CommentsBindingInLambda.kt");
|
||||
doParsingTest(fileName);
|
||||
}
|
||||
|
||||
@TestMetadata("CommentsBindingInStatementBlock.kt")
|
||||
public void testCommentsBindingInStatementBlock() throws Exception {
|
||||
String fileName = KotlinTestUtils.navigationMetadata("compiler/testData/psi/CommentsBindingInStatementBlock.kt");
|
||||
doParsingTest(fileName);
|
||||
}
|
||||
|
||||
@TestMetadata("Constructors.kt")
|
||||
public void testConstructors() throws Exception {
|
||||
String fileName = KotlinTestUtils.navigationMetadata("compiler/testData/psi/Constructors.kt");
|
||||
@@ -541,6 +553,12 @@ public class ParsingTestGenerated extends AbstractParsingTest {
|
||||
doParsingTest(fileName);
|
||||
}
|
||||
|
||||
@TestMetadata("LineCommentsInBlock.kt")
|
||||
public void testLineCommentsInBlock() throws Exception {
|
||||
String fileName = KotlinTestUtils.navigationMetadata("compiler/testData/psi/LineCommentsInBlock.kt");
|
||||
doParsingTest(fileName);
|
||||
}
|
||||
|
||||
@TestMetadata("LocalDeclarations.kt")
|
||||
public void testLocalDeclarations() throws Exception {
|
||||
String fileName = KotlinTestUtils.navigationMetadata("compiler/testData/psi/LocalDeclarations.kt");
|
||||
|
||||
+2
-1
@@ -4,7 +4,8 @@
|
||||
fun foo(list: List<String>) {
|
||||
// string should be non-empty
|
||||
// save it into result
|
||||
val result: String? = list.firstOrNull { // search for first non-empty string in the list
|
||||
val result: String? = list.firstOrNull {
|
||||
// search for first non-empty string in the list
|
||||
it.length > 0
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user