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
|
package org.jetbrains.kotlin.parsing
|
||||||
|
|
||||||
import com.intellij.lang.WhitespacesAndCommentsBinder
|
import com.intellij.lang.WhitespacesAndCommentsBinder
|
||||||
|
import com.intellij.openapi.util.text.StringUtil
|
||||||
import com.intellij.psi.tree.IElementType
|
import com.intellij.psi.tree.IElementType
|
||||||
import org.jetbrains.kotlin.lexer.KtTokens
|
import org.jetbrains.kotlin.lexer.KtTokens
|
||||||
import com.intellij.openapi.util.text.StringUtil
|
|
||||||
|
|
||||||
object PrecedingCommentsBinder : WhitespacesAndCommentsBinder {
|
object PrecedingCommentsBinder : WhitespacesAndCommentsBinder {
|
||||||
|
override fun getEdgePosition(
|
||||||
override fun getEdgePosition(tokens: List<IElementType>, atStreamEdge: Boolean, getter: WhitespacesAndCommentsBinder.TokenTextGetter): Int {
|
tokens: List<IElementType>, atStreamEdge: Boolean, getter: WhitespacesAndCommentsBinder.TokenTextGetter): Int {
|
||||||
if (tokens.isEmpty()) return 0
|
if (tokens.isEmpty()) return 0
|
||||||
|
|
||||||
// 1. bind doc comment
|
// 1. bind doc comment
|
||||||
@@ -53,8 +53,8 @@ object PrecedingCommentsBinder : WhitespacesAndCommentsBinder {
|
|||||||
}
|
}
|
||||||
|
|
||||||
object PrecedingDocCommentsBinder : WhitespacesAndCommentsBinder {
|
object PrecedingDocCommentsBinder : WhitespacesAndCommentsBinder {
|
||||||
|
override fun getEdgePosition(
|
||||||
override fun getEdgePosition(tokens: List<IElementType>, atStreamEdge: Boolean, getter: WhitespacesAndCommentsBinder.TokenTextGetter): Int {
|
tokens: List<IElementType>, atStreamEdge: Boolean, getter: WhitespacesAndCommentsBinder.TokenTextGetter): Int {
|
||||||
if (tokens.isEmpty()) return 0
|
if (tokens.isEmpty()) return 0
|
||||||
|
|
||||||
for (idx in tokens.indices.reversed()) {
|
for (idx in tokens.indices.reversed()) {
|
||||||
@@ -67,8 +67,8 @@ object PrecedingDocCommentsBinder : WhitespacesAndCommentsBinder {
|
|||||||
|
|
||||||
// Binds comments on the same line
|
// Binds comments on the same line
|
||||||
object TrailingCommentsBinder : WhitespacesAndCommentsBinder {
|
object TrailingCommentsBinder : WhitespacesAndCommentsBinder {
|
||||||
|
override fun getEdgePosition(
|
||||||
override fun getEdgePosition(tokens: List<IElementType>, atStreamEdge: Boolean, getter: WhitespacesAndCommentsBinder.TokenTextGetter): Int {
|
tokens: List<IElementType>, atStreamEdge: Boolean, getter: WhitespacesAndCommentsBinder.TokenTextGetter): Int {
|
||||||
if (tokens.isEmpty()) return 0
|
if (tokens.isEmpty()) return 0
|
||||||
|
|
||||||
var result = 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 {
|
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
|
return 0
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -1091,7 +1091,9 @@ public class KotlinExpressionParsing extends AbstractKotlinParsing {
|
|||||||
else {
|
else {
|
||||||
PsiBuilder.Marker body = mark();
|
PsiBuilder.Marker body = mark();
|
||||||
parseStatements();
|
parseStatements();
|
||||||
|
|
||||||
body.done(BLOCK);
|
body.done(BLOCK);
|
||||||
|
body.setCustomEdgeTokenBinders(CommentBindersKt.PRECEDING_ALL_COMMENTS_BINDER, CommentBindersKt.TRAILING_ALL_COMMENTS_BINDER);
|
||||||
|
|
||||||
expect(RBRACE, "Expecting '}'");
|
expect(RBRACE, "Expecting '}'");
|
||||||
literal.done(FUNCTION_LITERAL);
|
literal.done(FUNCTION_LITERAL);
|
||||||
|
|||||||
+21
-21
@@ -305,30 +305,30 @@ sink:
|
|||||||
}
|
}
|
||||||
---------------------
|
---------------------
|
||||||
L3:
|
L3:
|
||||||
2 <START> INIT: in: {some=D} out: {some=D}
|
2 <START> INIT: in: {some=D} out: {some=D}
|
||||||
3 mark(if (state) state = true println(state))
|
3 mark(if (state) state = true println(state) // OK)
|
||||||
mark(if (state) state = true)
|
mark(if (state) state = true)
|
||||||
magic[IMPLICIT_RECEIVER](state) -> <v0>
|
magic[IMPLICIT_RECEIVER](state) -> <v0>
|
||||||
r(state|<v0>) -> <v1>
|
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>
|
magic[IMPLICIT_RECEIVER](state) -> <v2>
|
||||||
r(true) -> <v3> USE: in: {state=WRITTEN_AFTER_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}
|
w(state|<v2>, <v3>) USE: in: {state=READ} out: {state=WRITTEN_AFTER_READ}
|
||||||
jmp(L6)
|
jmp(L6)
|
||||||
L5 [else branch]:
|
L5 [else branch]:
|
||||||
read (Unit)
|
read (Unit)
|
||||||
L6 ['if' expression result]:
|
L6 ['if' expression result]:
|
||||||
merge(if (state) state = true|!<v4>) -> <v5>
|
merge(if (state) state = true|!<v4>) -> <v5>
|
||||||
magic[IMPLICIT_RECEIVER](state) -> <v6> USE: in: {state=READ} out: {state=READ}
|
magic[IMPLICIT_RECEIVER](state) -> <v6> USE: in: {state=READ} out: {state=READ}
|
||||||
r(state|<v6>) -> <v7> USE: in: {} out: {state=READ}
|
r(state|<v6>) -> <v7> USE: in: {} out: {state=READ}
|
||||||
mark(println(state))
|
mark(println(state))
|
||||||
call(println(state), println|<v7>) -> <v8>
|
call(println(state), println|<v7>) -> <v8>
|
||||||
L4:
|
L4:
|
||||||
2 <END>
|
2 <END>
|
||||||
error:
|
error:
|
||||||
<ERROR> INIT: in: {} out: {}
|
<ERROR> INIT: in: {} out: {}
|
||||||
sink:
|
sink:
|
||||||
<SINK> INIT: in: {some=I?} out: {some=I?} USE: in: {} out: {}
|
<SINK> INIT: in: {some=I?} out: {some=I?} USE: in: {} out: {}
|
||||||
=====================
|
=====================
|
||||||
== exec ==
|
== exec ==
|
||||||
fun <T> exec(f: () -> T): T = f()
|
fun <T> exec(f: () -> T): T = f()
|
||||||
@@ -391,30 +391,30 @@ sink:
|
|||||||
}
|
}
|
||||||
---------------------
|
---------------------
|
||||||
L3:
|
L3:
|
||||||
2 <START> INIT: in: {some=D} out: {some=D}
|
2 <START> INIT: in: {some=D} out: {some=D}
|
||||||
3 mark(if (state) state = true println(state))
|
3 mark(if (state) state = true println(state) // must be initialized)
|
||||||
mark(if (state) state = true)
|
mark(if (state) state = true)
|
||||||
magic[IMPLICIT_RECEIVER](state) -> <v0>
|
magic[IMPLICIT_RECEIVER](state) -> <v0>
|
||||||
r(state|<v0>) -> <v1>
|
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>
|
magic[IMPLICIT_RECEIVER](state) -> <v2>
|
||||||
r(true) -> <v3> USE: in: {state=WRITTEN_AFTER_READ} out: {state=WRITTEN_AFTER_READ}
|
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}
|
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}
|
jmp(L6) INIT: in: {some=D, state=I} out: {some=D, state=I}
|
||||||
L5 [else branch]:
|
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]:
|
L6 ['if' expression result]:
|
||||||
merge(if (state) state = true|!<v4>) -> <v5> INIT: in: {some=D, state=I} out: {some=D, state=I}
|
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}
|
magic[IMPLICIT_RECEIVER](state) -> <v6> USE: in: {state=READ} out: {state=READ}
|
||||||
r(state|<v6>) -> <v7> USE: in: {} out: {state=READ}
|
r(state|<v6>) -> <v7> USE: in: {} out: {state=READ}
|
||||||
mark(println(state))
|
mark(println(state))
|
||||||
call(println(state), println|<v7>) -> <v8>
|
call(println(state), println|<v7>) -> <v8>
|
||||||
L4:
|
L4:
|
||||||
2 <END>
|
2 <END>
|
||||||
error:
|
error:
|
||||||
<ERROR> INIT: in: {} out: {}
|
<ERROR> INIT: in: {} out: {}
|
||||||
sink:
|
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 ==
|
== Demo5 ==
|
||||||
class Demo5 {
|
class Demo5 {
|
||||||
|
|||||||
@@ -164,16 +164,16 @@ true <v3>: Boolean
|
|||||||
println(state) // OK
|
println(state) // OK
|
||||||
}
|
}
|
||||||
---------------------
|
---------------------
|
||||||
<v0>: Demo3 NEW: magic[IMPLICIT_RECEIVER](state) -> <v0>
|
<v0>: Demo3 NEW: magic[IMPLICIT_RECEIVER](state) -> <v0>
|
||||||
<v2>: Demo3 NEW: magic[IMPLICIT_RECEIVER](state) -> <v2>
|
<v2>: Demo3 NEW: magic[IMPLICIT_RECEIVER](state) -> <v2>
|
||||||
<v6>: Demo3 NEW: magic[IMPLICIT_RECEIVER](state) -> <v6>
|
<v6>: Demo3 NEW: magic[IMPLICIT_RECEIVER](state) -> <v6>
|
||||||
state <v1>: Boolean NEW: r(state|<v0>) -> <v1>
|
state <v1>: Boolean NEW: r(state|<v0>) -> <v1>
|
||||||
true <v3>: Boolean NEW: r(true) -> <v3>
|
true <v3>: Boolean NEW: r(true) -> <v3>
|
||||||
state = true !<v4>: *
|
state = true !<v4>: *
|
||||||
if (state) state = true <v5>: * NEW: merge(if (state) state = true|!<v4>) -> <v5>
|
if (state) state = true <v5>: * NEW: merge(if (state) state = true|!<v4>) -> <v5>
|
||||||
state <v7>: * NEW: r(state|<v6>) -> <v7>
|
state <v7>: * NEW: r(state|<v6>) -> <v7>
|
||||||
println(state) <v8>: * NEW: call(println(state), println|<v7>) -> <v8>
|
println(state) <v8>: * NEW: call(println(state), println|<v7>) -> <v8>
|
||||||
if (state) state = true println(state) <v8>: * COPY
|
if (state) state = true println(state) // OK <v8>: * COPY
|
||||||
=====================
|
=====================
|
||||||
== exec ==
|
== exec ==
|
||||||
fun <T> exec(f: () -> T): T = f()
|
fun <T> exec(f: () -> T): T = f()
|
||||||
@@ -206,16 +206,16 @@ true <v2>: B
|
|||||||
println(state) // must be initialized
|
println(state) // must be initialized
|
||||||
}
|
}
|
||||||
---------------------
|
---------------------
|
||||||
<v0>: Demo4 NEW: magic[IMPLICIT_RECEIVER](state) -> <v0>
|
<v0>: Demo4 NEW: magic[IMPLICIT_RECEIVER](state) -> <v0>
|
||||||
<v2>: Demo4 NEW: magic[IMPLICIT_RECEIVER](state) -> <v2>
|
<v2>: Demo4 NEW: magic[IMPLICIT_RECEIVER](state) -> <v2>
|
||||||
<v6>: Demo4 NEW: magic[IMPLICIT_RECEIVER](state) -> <v6>
|
<v6>: Demo4 NEW: magic[IMPLICIT_RECEIVER](state) -> <v6>
|
||||||
state <v1>: Boolean NEW: r(state|<v0>) -> <v1>
|
state <v1>: Boolean NEW: r(state|<v0>) -> <v1>
|
||||||
true <v3>: Boolean NEW: r(true) -> <v3>
|
true <v3>: Boolean NEW: r(true) -> <v3>
|
||||||
state = true !<v4>: *
|
state = true !<v4>: *
|
||||||
if (state) state = true <v5>: * NEW: merge(if (state) state = true|!<v4>) -> <v5>
|
if (state) state = true <v5>: * NEW: merge(if (state) state = true|!<v4>) -> <v5>
|
||||||
state <v7>: * NEW: r(state|<v6>) -> <v7>
|
state <v7>: * NEW: r(state|<v6>) -> <v7>
|
||||||
println(state) <v8>: * NEW: call(println(state), println|<v7>) -> <v8>
|
println(state) <v8>: * NEW: call(println(state), println|<v7>) -> <v8>
|
||||||
if (state) state = true println(state) <v8>: * COPY
|
if (state) state = true println(state) // must be initialized <v8>: * COPY
|
||||||
=====================
|
=====================
|
||||||
== Demo5 ==
|
== Demo5 ==
|
||||||
class Demo5 {
|
class Demo5 {
|
||||||
|
|||||||
@@ -58,15 +58,15 @@ sink:
|
|||||||
---------------------
|
---------------------
|
||||||
L3:
|
L3:
|
||||||
3 <START>
|
3 <START>
|
||||||
4 mark(return nonLocal)
|
4 mark(return nonLocal //unreachable)
|
||||||
r(nonLocal) -> <v0>
|
r(nonLocal) -> <v0>
|
||||||
ret(*|<v0>) L1 NEXT:[<END>]
|
ret(*|<v0>) L1 NEXT:[<END>]
|
||||||
L4:
|
L4:
|
||||||
3 <END> NEXT:[<SINK>] PREV:[]
|
3 <END> NEXT:[<SINK>] PREV:[]
|
||||||
error:
|
error:
|
||||||
<ERROR> PREV:[]
|
<ERROR> PREV:[]
|
||||||
sink:
|
sink:
|
||||||
<SINK> PREV:[<ERROR>, <END>]
|
<SINK> PREV:[<ERROR>, <END>]
|
||||||
=====================
|
=====================
|
||||||
== doSomething ==
|
== doSomething ==
|
||||||
fun doSomething() {}
|
fun doSomething() {}
|
||||||
|
|||||||
+3
-3
@@ -26,9 +26,9 @@ return "NON_LOCAL_FAILED $localResult"
|
|||||||
return nonLocal //unreachable
|
return nonLocal //unreachable
|
||||||
}
|
}
|
||||||
---------------------
|
---------------------
|
||||||
nonLocal <v0>: String NEW: r(nonLocal) -> <v0>
|
nonLocal <v0>: String NEW: r(nonLocal) -> <v0>
|
||||||
return nonLocal !<v1>: *
|
return nonLocal !<v1>: *
|
||||||
return nonLocal !<v1>: * COPY
|
return nonLocal //unreachable !<v1>: * COPY
|
||||||
=====================
|
=====================
|
||||||
== doSomething ==
|
== doSomething ==
|
||||||
fun 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
|
FUNCTION_LITERAL
|
||||||
PsiElement(LBRACE)('{')
|
PsiElement(LBRACE)('{')
|
||||||
PsiWhiteSpace(' ')
|
PsiWhiteSpace(' ')
|
||||||
PsiComment(EOL_COMMENT)('// parsed as array access')
|
|
||||||
PsiWhiteSpace('\n ')
|
|
||||||
BLOCK
|
BLOCK
|
||||||
|
PsiComment(EOL_COMMENT)('// parsed as array access')
|
||||||
|
PsiWhiteSpace('\n ')
|
||||||
CALL_EXPRESSION
|
CALL_EXPRESSION
|
||||||
REFERENCE_EXPRESSION
|
REFERENCE_EXPRESSION
|
||||||
PsiElement(IDENTIFIER)('print')
|
PsiElement(IDENTIFIER)('print')
|
||||||
|
|||||||
+6
-6
@@ -33,9 +33,9 @@ JetFile: recovery.kt
|
|||||||
FUNCTION_LITERAL
|
FUNCTION_LITERAL
|
||||||
PsiElement(LBRACE)('{')
|
PsiElement(LBRACE)('{')
|
||||||
PsiWhiteSpace(' ')
|
PsiWhiteSpace(' ')
|
||||||
PsiComment(EOL_COMMENT)('// should be no space after c')
|
|
||||||
PsiWhiteSpace('\n ')
|
|
||||||
BLOCK
|
BLOCK
|
||||||
|
PsiComment(EOL_COMMENT)('// should be no space after c')
|
||||||
|
PsiWhiteSpace('\n ')
|
||||||
RETURN
|
RETURN
|
||||||
PsiElement(return)('return')
|
PsiElement(return)('return')
|
||||||
PsiWhiteSpace(' ')
|
PsiWhiteSpace(' ')
|
||||||
@@ -61,9 +61,9 @@ JetFile: recovery.kt
|
|||||||
FUNCTION_LITERAL
|
FUNCTION_LITERAL
|
||||||
PsiElement(LBRACE)('{')
|
PsiElement(LBRACE)('{')
|
||||||
PsiWhiteSpace(' ')
|
PsiWhiteSpace(' ')
|
||||||
PsiComment(EOL_COMMENT)('// no label identifier')
|
|
||||||
PsiWhiteSpace('\n ')
|
|
||||||
BLOCK
|
BLOCK
|
||||||
|
PsiComment(EOL_COMMENT)('// no label identifier')
|
||||||
|
PsiWhiteSpace('\n ')
|
||||||
RETURN
|
RETURN
|
||||||
PsiElement(return)('return')
|
PsiElement(return)('return')
|
||||||
PsiWhiteSpace(' ')
|
PsiWhiteSpace(' ')
|
||||||
@@ -94,9 +94,9 @@ JetFile: recovery.kt
|
|||||||
FUNCTION_LITERAL
|
FUNCTION_LITERAL
|
||||||
PsiElement(LBRACE)('{')
|
PsiElement(LBRACE)('{')
|
||||||
PsiWhiteSpace(' ')
|
PsiWhiteSpace(' ')
|
||||||
PsiComment(EOL_COMMENT)('// should be no space after loop2')
|
|
||||||
PsiWhiteSpace('\n ')
|
|
||||||
BLOCK
|
BLOCK
|
||||||
|
PsiComment(EOL_COMMENT)('// should be no space after loop2')
|
||||||
|
PsiWhiteSpace('\n ')
|
||||||
RETURN
|
RETURN
|
||||||
PsiElement(return)('return')
|
PsiElement(return)('return')
|
||||||
PsiErrorElement:Label must be named
|
PsiErrorElement:Label must be named
|
||||||
|
|||||||
@@ -127,6 +127,18 @@ public class ParsingTestGenerated extends AbstractParsingTest {
|
|||||||
doParsingTest(fileName);
|
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")
|
@TestMetadata("Constructors.kt")
|
||||||
public void testConstructors() throws Exception {
|
public void testConstructors() throws Exception {
|
||||||
String fileName = KotlinTestUtils.navigationMetadata("compiler/testData/psi/Constructors.kt");
|
String fileName = KotlinTestUtils.navigationMetadata("compiler/testData/psi/Constructors.kt");
|
||||||
@@ -541,6 +553,12 @@ public class ParsingTestGenerated extends AbstractParsingTest {
|
|||||||
doParsingTest(fileName);
|
doParsingTest(fileName);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@TestMetadata("LineCommentsInBlock.kt")
|
||||||
|
public void testLineCommentsInBlock() throws Exception {
|
||||||
|
String fileName = KotlinTestUtils.navigationMetadata("compiler/testData/psi/LineCommentsInBlock.kt");
|
||||||
|
doParsingTest(fileName);
|
||||||
|
}
|
||||||
|
|
||||||
@TestMetadata("LocalDeclarations.kt")
|
@TestMetadata("LocalDeclarations.kt")
|
||||||
public void testLocalDeclarations() throws Exception {
|
public void testLocalDeclarations() throws Exception {
|
||||||
String fileName = KotlinTestUtils.navigationMetadata("compiler/testData/psi/LocalDeclarations.kt");
|
String fileName = KotlinTestUtils.navigationMetadata("compiler/testData/psi/LocalDeclarations.kt");
|
||||||
|
|||||||
+2
-1
@@ -4,7 +4,8 @@
|
|||||||
fun foo(list: List<String>) {
|
fun foo(list: List<String>) {
|
||||||
// string should be non-empty
|
// string should be non-empty
|
||||||
// save it into result
|
// 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
|
it.length > 0
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
Reference in New Issue
Block a user