Implement recovery for incomplete expression before declaration
It's needed when declarations are parsed as a part of previous expression (see tests) Currently we apply this kind of recovery in a conservative way, only when declaration starts at the next line, and while the condition could be relaxed, there's no need to do this #KT-4948 Fixed #KT-7118 Fixed
This commit is contained in:
@@ -21,6 +21,7 @@ import com.intellij.lang.PsiBuilder;
|
|||||||
import com.intellij.psi.tree.IElementType;
|
import com.intellij.psi.tree.IElementType;
|
||||||
import com.intellij.psi.tree.TokenSet;
|
import com.intellij.psi.tree.TokenSet;
|
||||||
import org.jetbrains.annotations.NotNull;
|
import org.jetbrains.annotations.NotNull;
|
||||||
|
import org.jetbrains.annotations.Nullable;
|
||||||
import org.jetbrains.kotlin.KtNodeType;
|
import org.jetbrains.kotlin.KtNodeType;
|
||||||
import org.jetbrains.kotlin.KtNodeTypes;
|
import org.jetbrains.kotlin.KtNodeTypes;
|
||||||
import org.jetbrains.kotlin.lexer.KtToken;
|
import org.jetbrains.kotlin.lexer.KtToken;
|
||||||
@@ -42,6 +43,9 @@ public class KotlinExpressionParsing extends AbstractKotlinParsing {
|
|||||||
|
|
||||||
private static final ImmutableMap<String, KtToken> KEYWORD_TEXTS = tokenSetToMap(KEYWORDS);
|
private static final ImmutableMap<String, KtToken> KEYWORD_TEXTS = tokenSetToMap(KEYWORDS);
|
||||||
|
|
||||||
|
private static final IElementType[] LOCAL_DECLARATION_FIRST =
|
||||||
|
new IElementType[] {CLASS_KEYWORD, INTERFACE_KEYWORD, FUN_KEYWORD, VAL_KEYWORD, VAR_KEYWORD, TYPE_ALIAS_KEYWORD};
|
||||||
|
|
||||||
private static ImmutableMap<String, KtToken> tokenSetToMap(TokenSet tokens) {
|
private static ImmutableMap<String, KtToken> tokenSetToMap(TokenSet tokens) {
|
||||||
ImmutableMap.Builder<String, KtToken> builder = ImmutableMap.builder();
|
ImmutableMap.Builder<String, KtToken> builder = ImmutableMap.builder();
|
||||||
for (IElementType token : tokens.getTypes()) {
|
for (IElementType token : tokens.getTypes()) {
|
||||||
@@ -298,8 +302,6 @@ public class KotlinExpressionParsing extends AbstractKotlinParsing {
|
|||||||
* see the precedence table
|
* see the precedence table
|
||||||
*/
|
*/
|
||||||
private void parseBinaryExpression(Precedence precedence) {
|
private void parseBinaryExpression(Precedence precedence) {
|
||||||
// System.out.println(precedence.name() + " at " + myBuilder.getTokenText());
|
|
||||||
|
|
||||||
PsiBuilder.Marker expression = mark();
|
PsiBuilder.Marker expression = mark();
|
||||||
|
|
||||||
precedence.parseHigherPrecedence(this);
|
precedence.parseHigherPrecedence(this);
|
||||||
@@ -331,10 +333,8 @@ public class KotlinExpressionParsing extends AbstractKotlinParsing {
|
|||||||
* operation? prefixExpression
|
* operation? prefixExpression
|
||||||
*/
|
*/
|
||||||
private void parsePrefixExpression() {
|
private void parsePrefixExpression() {
|
||||||
// System.out.println("pre at " + myBuilder.getTokenText());
|
|
||||||
|
|
||||||
if (at(AT)) {
|
if (at(AT)) {
|
||||||
if (!parseLocalDeclaration()) {
|
if (!parseLocalDeclaration(/* rollbackIfDefinitelyNotExpression = */ false)) {
|
||||||
PsiBuilder.Marker expression = mark();
|
PsiBuilder.Marker expression = mark();
|
||||||
myKotlinParsing.parseAnnotations(DEFAULT);
|
myKotlinParsing.parseAnnotations(DEFAULT);
|
||||||
parsePrefixExpression();
|
parsePrefixExpression();
|
||||||
@@ -454,7 +454,7 @@ public class KotlinExpressionParsing extends AbstractKotlinParsing {
|
|||||||
expression = mark();
|
expression = mark();
|
||||||
}
|
}
|
||||||
|
|
||||||
parseCallExpression();
|
parseSelectorCallExpression();
|
||||||
|
|
||||||
if (firstExpressionParsed) {
|
if (firstExpressionParsed) {
|
||||||
expression.done(expressionType);
|
expression.done(expressionType);
|
||||||
@@ -515,7 +515,7 @@ public class KotlinExpressionParsing extends AbstractKotlinParsing {
|
|||||||
/*
|
/*
|
||||||
* atomicExpression typeParameters? valueParameters? functionLiteral*
|
* atomicExpression typeParameters? valueParameters? functionLiteral*
|
||||||
*/
|
*/
|
||||||
private void parseCallExpression() {
|
private void parseSelectorCallExpression() {
|
||||||
PsiBuilder.Marker mark = mark();
|
PsiBuilder.Marker mark = mark();
|
||||||
parseAtomicExpression();
|
parseAtomicExpression();
|
||||||
if (!myBuilder.newlineBeforeCurrentToken() && parseCallSuffix()) {
|
if (!myBuilder.newlineBeforeCurrentToken() && parseCallSuffix()) {
|
||||||
@@ -624,8 +624,6 @@ public class KotlinExpressionParsing extends AbstractKotlinParsing {
|
|||||||
* ;
|
* ;
|
||||||
*/
|
*/
|
||||||
private boolean parseAtomicExpression() {
|
private boolean parseAtomicExpression() {
|
||||||
// System.out.println("atom at " + myBuilder.getTokenText());
|
|
||||||
|
|
||||||
boolean ok = true;
|
boolean ok = true;
|
||||||
|
|
||||||
if (at(LPAR)) {
|
if (at(LPAR)) {
|
||||||
@@ -670,9 +668,9 @@ public class KotlinExpressionParsing extends AbstractKotlinParsing {
|
|||||||
else if (at(DO_KEYWORD)) {
|
else if (at(DO_KEYWORD)) {
|
||||||
parseDoWhile();
|
parseDoWhile();
|
||||||
}
|
}
|
||||||
else if (atSet(CLASS_KEYWORD, INTERFACE_KEYWORD, FUN_KEYWORD, VAL_KEYWORD,
|
else if (atSet(LOCAL_DECLARATION_FIRST) &&
|
||||||
VAR_KEYWORD, TYPE_ALIAS_KEYWORD)) {
|
parseLocalDeclaration(/* rollbackIfDefinitelyNotExpression = */ myBuilder.newlineBeforeCurrentToken())) {
|
||||||
parseLocalDeclaration();
|
// declaration was parsed, do nothing
|
||||||
}
|
}
|
||||||
else if (at(IDENTIFIER)) {
|
else if (at(IDENTIFIER)) {
|
||||||
parseSimpleNameExpression();
|
parseSimpleNameExpression();
|
||||||
@@ -1018,12 +1016,12 @@ public class KotlinExpressionParsing extends AbstractKotlinParsing {
|
|||||||
/*
|
/*
|
||||||
* modifiers declarationRest
|
* modifiers declarationRest
|
||||||
*/
|
*/
|
||||||
private boolean parseLocalDeclaration() {
|
private boolean parseLocalDeclaration(boolean rollbackIfDefinitelyNotExpression) {
|
||||||
PsiBuilder.Marker decl = mark();
|
PsiBuilder.Marker decl = mark();
|
||||||
KotlinParsing.ModifierDetector detector = new KotlinParsing.ModifierDetector();
|
KotlinParsing.ModifierDetector detector = new KotlinParsing.ModifierDetector();
|
||||||
myKotlinParsing.parseModifierList(detector, DEFAULT, TokenSet.EMPTY);
|
myKotlinParsing.parseModifierList(detector, DEFAULT, TokenSet.EMPTY);
|
||||||
|
|
||||||
IElementType declType = parseLocalDeclarationRest(detector.isEnumDetected());
|
IElementType declType = parseLocalDeclarationRest(detector.isEnumDetected(), rollbackIfDefinitelyNotExpression);
|
||||||
|
|
||||||
if (declType != null) {
|
if (declType != null) {
|
||||||
// we do not attach preceding comments (non-doc) to local variables because they are likely commenting a few statements below
|
// we do not attach preceding comments (non-doc) to local variables because they are likely commenting a few statements below
|
||||||
@@ -1220,7 +1218,7 @@ public class KotlinExpressionParsing extends AbstractKotlinParsing {
|
|||||||
* ;
|
* ;
|
||||||
*/
|
*/
|
||||||
private void parseStatement(boolean isScriptTopLevel) {
|
private void parseStatement(boolean isScriptTopLevel) {
|
||||||
if (!parseLocalDeclaration()) {
|
if (!parseLocalDeclaration(/* rollbackIfDefinitelyNotExpression = */false)) {
|
||||||
if (!atSet(EXPRESSION_FIRST)) {
|
if (!atSet(EXPRESSION_FIRST)) {
|
||||||
errorAndAdvance("Expecting a statement");
|
errorAndAdvance("Expecting a statement");
|
||||||
}
|
}
|
||||||
@@ -1245,9 +1243,17 @@ public class KotlinExpressionParsing extends AbstractKotlinParsing {
|
|||||||
* : object
|
* : object
|
||||||
* ;
|
* ;
|
||||||
*/
|
*/
|
||||||
private IElementType parseLocalDeclarationRest(boolean isEnum) {
|
@Nullable
|
||||||
|
private IElementType parseLocalDeclarationRest(boolean isEnum, boolean failIfDefinitelyNotExpression) {
|
||||||
IElementType keywordToken = tt();
|
IElementType keywordToken = tt();
|
||||||
IElementType declType = null;
|
IElementType declType = null;
|
||||||
|
|
||||||
|
if (failIfDefinitelyNotExpression) {
|
||||||
|
if (keywordToken != FUN_KEYWORD) return null;
|
||||||
|
|
||||||
|
return myKotlinParsing.parseFunction(/* failIfIdentifierExists = */ true);
|
||||||
|
}
|
||||||
|
|
||||||
if (keywordToken == CLASS_KEYWORD || keywordToken == INTERFACE_KEYWORD) {
|
if (keywordToken == CLASS_KEYWORD || keywordToken == INTERFACE_KEYWORD) {
|
||||||
declType = myKotlinParsing.parseClass(isEnum);
|
declType = myKotlinParsing.parseClass(isEnum);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -21,6 +21,7 @@ import com.intellij.lang.WhitespacesBinders;
|
|||||||
import com.intellij.openapi.diagnostic.Logger;
|
import com.intellij.openapi.diagnostic.Logger;
|
||||||
import com.intellij.psi.tree.IElementType;
|
import com.intellij.psi.tree.IElementType;
|
||||||
import com.intellij.psi.tree.TokenSet;
|
import com.intellij.psi.tree.TokenSet;
|
||||||
|
import org.jetbrains.annotations.Contract;
|
||||||
import org.jetbrains.annotations.NotNull;
|
import org.jetbrains.annotations.NotNull;
|
||||||
import org.jetbrains.annotations.Nullable;
|
import org.jetbrains.annotations.Nullable;
|
||||||
import org.jetbrains.kotlin.lexer.KtKeywordToken;
|
import org.jetbrains.kotlin.lexer.KtKeywordToken;
|
||||||
@@ -1444,6 +1445,11 @@ public class KotlinParsing extends AbstractKotlinParsing {
|
|||||||
return accessorKind;
|
return accessorKind;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@NotNull
|
||||||
|
IElementType parseFunction() {
|
||||||
|
return parseFunction(false);
|
||||||
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* function
|
* function
|
||||||
* : modifiers "fun" typeParameters?
|
* : modifiers "fun" typeParameters?
|
||||||
@@ -1454,7 +1460,8 @@ public class KotlinParsing extends AbstractKotlinParsing {
|
|||||||
* functionBody?
|
* functionBody?
|
||||||
* ;
|
* ;
|
||||||
*/
|
*/
|
||||||
IElementType parseFunction() {
|
@Contract("false -> !null")
|
||||||
|
IElementType parseFunction(boolean failIfIdentifierExists) {
|
||||||
assert _at(FUN_KEYWORD);
|
assert _at(FUN_KEYWORD);
|
||||||
|
|
||||||
advance(); // FUN_KEYWORD
|
advance(); // FUN_KEYWORD
|
||||||
@@ -1476,6 +1483,11 @@ public class KotlinParsing extends AbstractKotlinParsing {
|
|||||||
TokenSet functionNameFollow = TokenSet.create(LT, LPAR, RPAR, COLON, EQ);
|
TokenSet functionNameFollow = TokenSet.create(LT, LPAR, RPAR, COLON, EQ);
|
||||||
boolean receiverFound = parseReceiverType("function", functionNameFollow);
|
boolean receiverFound = parseReceiverType("function", functionNameFollow);
|
||||||
|
|
||||||
|
if (at(IDENTIFIER) && failIfIdentifierExists) {
|
||||||
|
myBuilder.restoreJoiningComplexTokensState();
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
// function as expression has no name
|
// function as expression has no name
|
||||||
parseFunctionOrPropertyName(receiverFound, "function", functionNameFollow, /*nameRequired = */ false);
|
parseFunctionOrPropertyName(receiverFound, "function", functionNameFollow, /*nameRequired = */ false);
|
||||||
|
|
||||||
@@ -1598,15 +1610,15 @@ public class KotlinParsing extends AbstractKotlinParsing {
|
|||||||
/*
|
/*
|
||||||
* IDENTIFIER
|
* IDENTIFIER
|
||||||
*/
|
*/
|
||||||
private void parseFunctionOrPropertyName(boolean receiverFound, String title, TokenSet nameFollow, boolean nameRequired) {
|
private boolean parseFunctionOrPropertyName(boolean receiverFound, String title, TokenSet nameFollow, boolean nameRequired) {
|
||||||
if (!nameRequired && atSet(nameFollow)) return; // no name
|
if (!nameRequired && atSet(nameFollow)) return true; // no name
|
||||||
|
|
||||||
TokenSet recoverySet = TokenSet.orSet(nameFollow, TokenSet.create(LBRACE, RBRACE), TOP_LEVEL_DECLARATION_FIRST);
|
TokenSet recoverySet = TokenSet.orSet(nameFollow, TokenSet.create(LBRACE, RBRACE), TOP_LEVEL_DECLARATION_FIRST);
|
||||||
if (!receiverFound) {
|
if (!receiverFound) {
|
||||||
expect(IDENTIFIER, "Expecting " + title + " name or receiver type", recoverySet);
|
return expect(IDENTIFIER, "Expecting " + title + " name or receiver type", recoverySet);
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
expect(IDENTIFIER, "Expecting " + title + " name", recoverySet);
|
return expect(IDENTIFIER, "Expecting " + title + " name", recoverySet);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
+6
-6
@@ -12,18 +12,18 @@ fun test() {
|
|||||||
val x1 =
|
val x1 =
|
||||||
if (1 == 1)
|
if (1 == 1)
|
||||||
// TODO: Diagnostic content could be better
|
// TODO: Diagnostic content could be better
|
||||||
<!EXPECTED_TYPE_MISMATCH(\(\) -> Int)!>fun named4(): Int {return 1}<!>
|
<!SYNTAX!><!>fun named4(): Int {return 1}
|
||||||
else
|
<!SYNTAX!>else<!>
|
||||||
<!EXPECTED_TYPE_MISMATCH!>fun named5() = 1<!>
|
fun named5() = 1
|
||||||
|
|
||||||
val x2 =
|
val x2 =
|
||||||
if (1 == 1) {
|
if (1 == 1) {
|
||||||
<!EXPECTED_TYPE_MISMATCH!>fun named6(): Int {
|
fun named6(): Int {
|
||||||
return 1
|
return 1
|
||||||
}<!>
|
}
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
<!EXPECTED_TYPE_MISMATCH!>fun named7() = 1<!>
|
<!SYNTAX!><!>fun named7() = 1
|
||||||
|
|
||||||
val x3 = when (1) {
|
val x3 = when (1) {
|
||||||
0 -> <!EXPECTED_TYPE_MISMATCH!>fun named8(): Int {return 1}<!>
|
0 -> <!EXPECTED_TYPE_MISMATCH!>fun named8(): Int {return 1}<!>
|
||||||
|
|||||||
+29
@@ -0,0 +1,29 @@
|
|||||||
|
// !DIAGNOSTICS: -UNUSED_VARIABLE
|
||||||
|
|
||||||
|
fun foo(x: Any) {
|
||||||
|
x.<!SYNTAX!><!>
|
||||||
|
val foo = 1
|
||||||
|
|
||||||
|
x.<!SYNTAX!><!>
|
||||||
|
fun bar() = 2
|
||||||
|
|
||||||
|
x.
|
||||||
|
<!ILLEGAL_SELECTOR!>fun String.() = 3<!>
|
||||||
|
|
||||||
|
var a = 24.<!SYNTAX!><!>
|
||||||
|
var b = 42.0
|
||||||
|
}
|
||||||
|
|
||||||
|
class A {
|
||||||
|
val z = "a".<!SYNTAX!><!>
|
||||||
|
val x = 4
|
||||||
|
|
||||||
|
val y = "b".<!SYNTAX!><!>
|
||||||
|
fun baz() = 5
|
||||||
|
|
||||||
|
val q = "c".
|
||||||
|
<!ILLEGAL_SELECTOR!>fun String.() = 6<!>
|
||||||
|
|
||||||
|
var a = 24.<!SYNTAX!><!>
|
||||||
|
var b = 42.0
|
||||||
|
}
|
||||||
+18
@@ -0,0 +1,18 @@
|
|||||||
|
package
|
||||||
|
|
||||||
|
public fun foo(/*0*/ x: kotlin.Any): kotlin.Unit
|
||||||
|
|
||||||
|
public final class A {
|
||||||
|
public constructor A()
|
||||||
|
public final var a: [ERROR : Type for 24.]
|
||||||
|
public final var b: kotlin.Double
|
||||||
|
public final val q: [ERROR : Type for "c".
|
||||||
|
fun String.() = 6]
|
||||||
|
public final val x: kotlin.Int = 4
|
||||||
|
public final val y: [ERROR : Type for "b".]
|
||||||
|
public final val z: [ERROR : Type for "a".]
|
||||||
|
public final fun baz(): kotlin.Int
|
||||||
|
public open override /*1*/ /*fake_override*/ fun equals(/*0*/ other: kotlin.Any?): kotlin.Boolean
|
||||||
|
public open override /*1*/ /*fake_override*/ fun hashCode(): kotlin.Int
|
||||||
|
public open override /*1*/ /*fake_override*/ fun toString(): kotlin.String
|
||||||
|
}
|
||||||
+22
@@ -0,0 +1,22 @@
|
|||||||
|
// !DIAGNOSTICS: -UNUSED_VARIABLE
|
||||||
|
fun foo(x: Any?) {
|
||||||
|
x ?:<!SYNTAX!><!>
|
||||||
|
val foo = 1
|
||||||
|
|
||||||
|
x ?:<!SYNTAX!><!>
|
||||||
|
fun bar() = 2
|
||||||
|
|
||||||
|
val res: String.() -> Int = null ?:
|
||||||
|
fun String.() = 3
|
||||||
|
}
|
||||||
|
|
||||||
|
class A {
|
||||||
|
val z = null ?:<!SYNTAX!><!>
|
||||||
|
val x = 4
|
||||||
|
|
||||||
|
val y = null ?:<!SYNTAX!><!>
|
||||||
|
fun baz() = 5
|
||||||
|
|
||||||
|
val q = null ?:
|
||||||
|
fun String.() = 6
|
||||||
|
}
|
||||||
+15
@@ -0,0 +1,15 @@
|
|||||||
|
package
|
||||||
|
|
||||||
|
public fun foo(/*0*/ x: kotlin.Any?): kotlin.Unit
|
||||||
|
|
||||||
|
public final class A {
|
||||||
|
public constructor A()
|
||||||
|
public final val q: kotlin.String.() -> kotlin.Int
|
||||||
|
public final val x: kotlin.Int = 4
|
||||||
|
public final val y: [ERROR : Type for null ?:]
|
||||||
|
public final val z: [ERROR : Type for null ?:]
|
||||||
|
public final fun baz(): kotlin.Int
|
||||||
|
public open override /*1*/ /*fake_override*/ fun equals(/*0*/ other: kotlin.Any?): kotlin.Boolean
|
||||||
|
public open override /*1*/ /*fake_override*/ fun hashCode(): kotlin.Int
|
||||||
|
public open override /*1*/ /*fake_override*/ fun toString(): kotlin.String
|
||||||
|
}
|
||||||
+3
-3
@@ -1,4 +1,4 @@
|
|||||||
fun foo(s: String) {
|
fun foo(s: String) {
|
||||||
s.
|
s.<!SYNTAX!><!>
|
||||||
<!DECLARATION_IN_ILLEGAL_CONTEXT, ILLEGAL_SELECTOR!>val b = 42<!>
|
val <!UNUSED_VARIABLE!>b<!> = 42
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -0,0 +1,27 @@
|
|||||||
|
fun foo(x: Any) {
|
||||||
|
x.
|
||||||
|
val foo = 1
|
||||||
|
|
||||||
|
x.
|
||||||
|
fun bar() = 2
|
||||||
|
|
||||||
|
x.
|
||||||
|
fun String.() = 3
|
||||||
|
|
||||||
|
var a = 24.
|
||||||
|
var b = 42.0
|
||||||
|
}
|
||||||
|
|
||||||
|
class A {
|
||||||
|
val z = "a".
|
||||||
|
val x = 4
|
||||||
|
|
||||||
|
val y = "b".
|
||||||
|
fun baz() = 5
|
||||||
|
|
||||||
|
val q = "c".
|
||||||
|
fun String.() = 6
|
||||||
|
|
||||||
|
var a = 24.
|
||||||
|
var b = 42.0
|
||||||
|
}
|
||||||
@@ -0,0 +1,231 @@
|
|||||||
|
JetFile: DeclarationAfterDotSelectorExpected.kt
|
||||||
|
PACKAGE_DIRECTIVE
|
||||||
|
<empty list>
|
||||||
|
IMPORT_LIST
|
||||||
|
<empty list>
|
||||||
|
FUN
|
||||||
|
PsiElement(fun)('fun')
|
||||||
|
PsiWhiteSpace(' ')
|
||||||
|
PsiElement(IDENTIFIER)('foo')
|
||||||
|
VALUE_PARAMETER_LIST
|
||||||
|
PsiElement(LPAR)('(')
|
||||||
|
VALUE_PARAMETER
|
||||||
|
PsiElement(IDENTIFIER)('x')
|
||||||
|
PsiElement(COLON)(':')
|
||||||
|
PsiWhiteSpace(' ')
|
||||||
|
TYPE_REFERENCE
|
||||||
|
USER_TYPE
|
||||||
|
REFERENCE_EXPRESSION
|
||||||
|
PsiElement(IDENTIFIER)('Any')
|
||||||
|
PsiElement(RPAR)(')')
|
||||||
|
PsiWhiteSpace(' ')
|
||||||
|
BLOCK
|
||||||
|
PsiElement(LBRACE)('{')
|
||||||
|
PsiWhiteSpace('\n ')
|
||||||
|
DOT_QUALIFIED_EXPRESSION
|
||||||
|
REFERENCE_EXPRESSION
|
||||||
|
PsiElement(IDENTIFIER)('x')
|
||||||
|
PsiElement(DOT)('.')
|
||||||
|
PsiErrorElement:Expecting an element
|
||||||
|
<empty list>
|
||||||
|
PsiWhiteSpace('\n ')
|
||||||
|
PROPERTY
|
||||||
|
PsiElement(val)('val')
|
||||||
|
PsiWhiteSpace(' ')
|
||||||
|
PsiElement(IDENTIFIER)('foo')
|
||||||
|
PsiWhiteSpace(' ')
|
||||||
|
PsiElement(EQ)('=')
|
||||||
|
PsiWhiteSpace(' ')
|
||||||
|
INTEGER_CONSTANT
|
||||||
|
PsiElement(INTEGER_LITERAL)('1')
|
||||||
|
PsiWhiteSpace('\n\n ')
|
||||||
|
DOT_QUALIFIED_EXPRESSION
|
||||||
|
REFERENCE_EXPRESSION
|
||||||
|
PsiElement(IDENTIFIER)('x')
|
||||||
|
PsiElement(DOT)('.')
|
||||||
|
PsiErrorElement:Expecting an element
|
||||||
|
<empty list>
|
||||||
|
PsiWhiteSpace('\n ')
|
||||||
|
FUN
|
||||||
|
PsiElement(fun)('fun')
|
||||||
|
PsiWhiteSpace(' ')
|
||||||
|
PsiElement(IDENTIFIER)('bar')
|
||||||
|
VALUE_PARAMETER_LIST
|
||||||
|
PsiElement(LPAR)('(')
|
||||||
|
PsiElement(RPAR)(')')
|
||||||
|
PsiWhiteSpace(' ')
|
||||||
|
PsiElement(EQ)('=')
|
||||||
|
PsiWhiteSpace(' ')
|
||||||
|
INTEGER_CONSTANT
|
||||||
|
PsiElement(INTEGER_LITERAL)('2')
|
||||||
|
PsiWhiteSpace('\n\n ')
|
||||||
|
DOT_QUALIFIED_EXPRESSION
|
||||||
|
REFERENCE_EXPRESSION
|
||||||
|
PsiElement(IDENTIFIER)('x')
|
||||||
|
PsiElement(DOT)('.')
|
||||||
|
PsiWhiteSpace('\n ')
|
||||||
|
FUN
|
||||||
|
PsiElement(fun)('fun')
|
||||||
|
PsiWhiteSpace(' ')
|
||||||
|
TYPE_REFERENCE
|
||||||
|
USER_TYPE
|
||||||
|
REFERENCE_EXPRESSION
|
||||||
|
PsiElement(IDENTIFIER)('String')
|
||||||
|
PsiElement(DOT)('.')
|
||||||
|
VALUE_PARAMETER_LIST
|
||||||
|
PsiElement(LPAR)('(')
|
||||||
|
PsiElement(RPAR)(')')
|
||||||
|
PsiWhiteSpace(' ')
|
||||||
|
PsiElement(EQ)('=')
|
||||||
|
PsiWhiteSpace(' ')
|
||||||
|
INTEGER_CONSTANT
|
||||||
|
PsiElement(INTEGER_LITERAL)('3')
|
||||||
|
PsiWhiteSpace('\n\n ')
|
||||||
|
PROPERTY
|
||||||
|
PsiElement(var)('var')
|
||||||
|
PsiWhiteSpace(' ')
|
||||||
|
PsiElement(IDENTIFIER)('a')
|
||||||
|
PsiWhiteSpace(' ')
|
||||||
|
PsiElement(EQ)('=')
|
||||||
|
PsiWhiteSpace(' ')
|
||||||
|
DOT_QUALIFIED_EXPRESSION
|
||||||
|
INTEGER_CONSTANT
|
||||||
|
PsiElement(INTEGER_LITERAL)('24')
|
||||||
|
PsiElement(DOT)('.')
|
||||||
|
PsiErrorElement:Expecting an element
|
||||||
|
<empty list>
|
||||||
|
PsiWhiteSpace('\n ')
|
||||||
|
PROPERTY
|
||||||
|
PsiElement(var)('var')
|
||||||
|
PsiWhiteSpace(' ')
|
||||||
|
PsiElement(IDENTIFIER)('b')
|
||||||
|
PsiWhiteSpace(' ')
|
||||||
|
PsiElement(EQ)('=')
|
||||||
|
PsiWhiteSpace(' ')
|
||||||
|
FLOAT_CONSTANT
|
||||||
|
PsiElement(FLOAT_CONSTANT)('42.0')
|
||||||
|
PsiWhiteSpace('\n')
|
||||||
|
PsiElement(RBRACE)('}')
|
||||||
|
PsiWhiteSpace('\n\n')
|
||||||
|
CLASS
|
||||||
|
PsiElement(class)('class')
|
||||||
|
PsiWhiteSpace(' ')
|
||||||
|
PsiElement(IDENTIFIER)('A')
|
||||||
|
PsiWhiteSpace(' ')
|
||||||
|
CLASS_BODY
|
||||||
|
PsiElement(LBRACE)('{')
|
||||||
|
PsiWhiteSpace('\n ')
|
||||||
|
PROPERTY
|
||||||
|
PsiElement(val)('val')
|
||||||
|
PsiWhiteSpace(' ')
|
||||||
|
PsiElement(IDENTIFIER)('z')
|
||||||
|
PsiWhiteSpace(' ')
|
||||||
|
PsiElement(EQ)('=')
|
||||||
|
PsiWhiteSpace(' ')
|
||||||
|
DOT_QUALIFIED_EXPRESSION
|
||||||
|
STRING_TEMPLATE
|
||||||
|
PsiElement(OPEN_QUOTE)('"')
|
||||||
|
LITERAL_STRING_TEMPLATE_ENTRY
|
||||||
|
PsiElement(REGULAR_STRING_PART)('a')
|
||||||
|
PsiElement(CLOSING_QUOTE)('"')
|
||||||
|
PsiElement(DOT)('.')
|
||||||
|
PsiErrorElement:Expecting an element
|
||||||
|
<empty list>
|
||||||
|
PsiWhiteSpace('\n ')
|
||||||
|
PROPERTY
|
||||||
|
PsiElement(val)('val')
|
||||||
|
PsiWhiteSpace(' ')
|
||||||
|
PsiElement(IDENTIFIER)('x')
|
||||||
|
PsiWhiteSpace(' ')
|
||||||
|
PsiElement(EQ)('=')
|
||||||
|
PsiWhiteSpace(' ')
|
||||||
|
INTEGER_CONSTANT
|
||||||
|
PsiElement(INTEGER_LITERAL)('4')
|
||||||
|
PsiWhiteSpace('\n\n ')
|
||||||
|
PROPERTY
|
||||||
|
PsiElement(val)('val')
|
||||||
|
PsiWhiteSpace(' ')
|
||||||
|
PsiElement(IDENTIFIER)('y')
|
||||||
|
PsiWhiteSpace(' ')
|
||||||
|
PsiElement(EQ)('=')
|
||||||
|
PsiWhiteSpace(' ')
|
||||||
|
DOT_QUALIFIED_EXPRESSION
|
||||||
|
STRING_TEMPLATE
|
||||||
|
PsiElement(OPEN_QUOTE)('"')
|
||||||
|
LITERAL_STRING_TEMPLATE_ENTRY
|
||||||
|
PsiElement(REGULAR_STRING_PART)('b')
|
||||||
|
PsiElement(CLOSING_QUOTE)('"')
|
||||||
|
PsiElement(DOT)('.')
|
||||||
|
PsiErrorElement:Expecting an element
|
||||||
|
<empty list>
|
||||||
|
PsiWhiteSpace('\n ')
|
||||||
|
FUN
|
||||||
|
PsiElement(fun)('fun')
|
||||||
|
PsiWhiteSpace(' ')
|
||||||
|
PsiElement(IDENTIFIER)('baz')
|
||||||
|
VALUE_PARAMETER_LIST
|
||||||
|
PsiElement(LPAR)('(')
|
||||||
|
PsiElement(RPAR)(')')
|
||||||
|
PsiWhiteSpace(' ')
|
||||||
|
PsiElement(EQ)('=')
|
||||||
|
PsiWhiteSpace(' ')
|
||||||
|
INTEGER_CONSTANT
|
||||||
|
PsiElement(INTEGER_LITERAL)('5')
|
||||||
|
PsiWhiteSpace('\n\n ')
|
||||||
|
PROPERTY
|
||||||
|
PsiElement(val)('val')
|
||||||
|
PsiWhiteSpace(' ')
|
||||||
|
PsiElement(IDENTIFIER)('q')
|
||||||
|
PsiWhiteSpace(' ')
|
||||||
|
PsiElement(EQ)('=')
|
||||||
|
PsiWhiteSpace(' ')
|
||||||
|
DOT_QUALIFIED_EXPRESSION
|
||||||
|
STRING_TEMPLATE
|
||||||
|
PsiElement(OPEN_QUOTE)('"')
|
||||||
|
LITERAL_STRING_TEMPLATE_ENTRY
|
||||||
|
PsiElement(REGULAR_STRING_PART)('c')
|
||||||
|
PsiElement(CLOSING_QUOTE)('"')
|
||||||
|
PsiElement(DOT)('.')
|
||||||
|
PsiWhiteSpace('\n ')
|
||||||
|
FUN
|
||||||
|
PsiElement(fun)('fun')
|
||||||
|
PsiWhiteSpace(' ')
|
||||||
|
TYPE_REFERENCE
|
||||||
|
USER_TYPE
|
||||||
|
REFERENCE_EXPRESSION
|
||||||
|
PsiElement(IDENTIFIER)('String')
|
||||||
|
PsiElement(DOT)('.')
|
||||||
|
VALUE_PARAMETER_LIST
|
||||||
|
PsiElement(LPAR)('(')
|
||||||
|
PsiElement(RPAR)(')')
|
||||||
|
PsiWhiteSpace(' ')
|
||||||
|
PsiElement(EQ)('=')
|
||||||
|
PsiWhiteSpace(' ')
|
||||||
|
INTEGER_CONSTANT
|
||||||
|
PsiElement(INTEGER_LITERAL)('6')
|
||||||
|
PsiWhiteSpace('\n\n ')
|
||||||
|
PROPERTY
|
||||||
|
PsiElement(var)('var')
|
||||||
|
PsiWhiteSpace(' ')
|
||||||
|
PsiElement(IDENTIFIER)('a')
|
||||||
|
PsiWhiteSpace(' ')
|
||||||
|
PsiElement(EQ)('=')
|
||||||
|
PsiWhiteSpace(' ')
|
||||||
|
DOT_QUALIFIED_EXPRESSION
|
||||||
|
INTEGER_CONSTANT
|
||||||
|
PsiElement(INTEGER_LITERAL)('24')
|
||||||
|
PsiElement(DOT)('.')
|
||||||
|
PsiErrorElement:Expecting an element
|
||||||
|
<empty list>
|
||||||
|
PsiWhiteSpace('\n ')
|
||||||
|
PROPERTY
|
||||||
|
PsiElement(var)('var')
|
||||||
|
PsiWhiteSpace(' ')
|
||||||
|
PsiElement(IDENTIFIER)('b')
|
||||||
|
PsiWhiteSpace(' ')
|
||||||
|
PsiElement(EQ)('=')
|
||||||
|
PsiWhiteSpace(' ')
|
||||||
|
FLOAT_CONSTANT
|
||||||
|
PsiElement(FLOAT_CONSTANT)('42.0')
|
||||||
|
PsiWhiteSpace('\n')
|
||||||
|
PsiElement(RBRACE)('}')
|
||||||
@@ -0,0 +1,21 @@
|
|||||||
|
fun foo(x: Any?) {
|
||||||
|
x ?:
|
||||||
|
val foo = 1
|
||||||
|
|
||||||
|
x ?:
|
||||||
|
fun bar() = 2
|
||||||
|
|
||||||
|
x ?:
|
||||||
|
fun String.() = 3
|
||||||
|
}
|
||||||
|
|
||||||
|
class A {
|
||||||
|
val z = null ?:
|
||||||
|
val x = 4
|
||||||
|
|
||||||
|
val y = null ?:
|
||||||
|
fun baz() = 5
|
||||||
|
|
||||||
|
val q = null ?:
|
||||||
|
fun String.() = 6
|
||||||
|
}
|
||||||
@@ -0,0 +1,188 @@
|
|||||||
|
JetFile: DeclarationAfterIncompleteElvis.kt
|
||||||
|
PACKAGE_DIRECTIVE
|
||||||
|
<empty list>
|
||||||
|
IMPORT_LIST
|
||||||
|
<empty list>
|
||||||
|
FUN
|
||||||
|
PsiElement(fun)('fun')
|
||||||
|
PsiWhiteSpace(' ')
|
||||||
|
PsiElement(IDENTIFIER)('foo')
|
||||||
|
VALUE_PARAMETER_LIST
|
||||||
|
PsiElement(LPAR)('(')
|
||||||
|
VALUE_PARAMETER
|
||||||
|
PsiElement(IDENTIFIER)('x')
|
||||||
|
PsiElement(COLON)(':')
|
||||||
|
PsiWhiteSpace(' ')
|
||||||
|
TYPE_REFERENCE
|
||||||
|
NULLABLE_TYPE
|
||||||
|
USER_TYPE
|
||||||
|
REFERENCE_EXPRESSION
|
||||||
|
PsiElement(IDENTIFIER)('Any')
|
||||||
|
PsiElement(QUEST)('?')
|
||||||
|
PsiElement(RPAR)(')')
|
||||||
|
PsiWhiteSpace(' ')
|
||||||
|
BLOCK
|
||||||
|
PsiElement(LBRACE)('{')
|
||||||
|
PsiWhiteSpace('\n ')
|
||||||
|
BINARY_EXPRESSION
|
||||||
|
REFERENCE_EXPRESSION
|
||||||
|
PsiElement(IDENTIFIER)('x')
|
||||||
|
PsiWhiteSpace(' ')
|
||||||
|
OPERATION_REFERENCE
|
||||||
|
PsiElement(ELVIS)('?:')
|
||||||
|
PsiErrorElement:Expecting an element
|
||||||
|
<empty list>
|
||||||
|
PsiWhiteSpace('\n ')
|
||||||
|
PROPERTY
|
||||||
|
PsiElement(val)('val')
|
||||||
|
PsiWhiteSpace(' ')
|
||||||
|
PsiElement(IDENTIFIER)('foo')
|
||||||
|
PsiWhiteSpace(' ')
|
||||||
|
PsiElement(EQ)('=')
|
||||||
|
PsiWhiteSpace(' ')
|
||||||
|
INTEGER_CONSTANT
|
||||||
|
PsiElement(INTEGER_LITERAL)('1')
|
||||||
|
PsiWhiteSpace('\n\n ')
|
||||||
|
BINARY_EXPRESSION
|
||||||
|
REFERENCE_EXPRESSION
|
||||||
|
PsiElement(IDENTIFIER)('x')
|
||||||
|
PsiWhiteSpace(' ')
|
||||||
|
OPERATION_REFERENCE
|
||||||
|
PsiElement(ELVIS)('?:')
|
||||||
|
PsiErrorElement:Expecting an element
|
||||||
|
<empty list>
|
||||||
|
PsiWhiteSpace('\n ')
|
||||||
|
FUN
|
||||||
|
PsiElement(fun)('fun')
|
||||||
|
PsiWhiteSpace(' ')
|
||||||
|
PsiElement(IDENTIFIER)('bar')
|
||||||
|
VALUE_PARAMETER_LIST
|
||||||
|
PsiElement(LPAR)('(')
|
||||||
|
PsiElement(RPAR)(')')
|
||||||
|
PsiWhiteSpace(' ')
|
||||||
|
PsiElement(EQ)('=')
|
||||||
|
PsiWhiteSpace(' ')
|
||||||
|
INTEGER_CONSTANT
|
||||||
|
PsiElement(INTEGER_LITERAL)('2')
|
||||||
|
PsiWhiteSpace('\n\n ')
|
||||||
|
BINARY_EXPRESSION
|
||||||
|
REFERENCE_EXPRESSION
|
||||||
|
PsiElement(IDENTIFIER)('x')
|
||||||
|
PsiWhiteSpace(' ')
|
||||||
|
OPERATION_REFERENCE
|
||||||
|
PsiElement(ELVIS)('?:')
|
||||||
|
PsiWhiteSpace('\n ')
|
||||||
|
FUN
|
||||||
|
PsiElement(fun)('fun')
|
||||||
|
PsiWhiteSpace(' ')
|
||||||
|
TYPE_REFERENCE
|
||||||
|
USER_TYPE
|
||||||
|
REFERENCE_EXPRESSION
|
||||||
|
PsiElement(IDENTIFIER)('String')
|
||||||
|
PsiElement(DOT)('.')
|
||||||
|
VALUE_PARAMETER_LIST
|
||||||
|
PsiElement(LPAR)('(')
|
||||||
|
PsiElement(RPAR)(')')
|
||||||
|
PsiWhiteSpace(' ')
|
||||||
|
PsiElement(EQ)('=')
|
||||||
|
PsiWhiteSpace(' ')
|
||||||
|
INTEGER_CONSTANT
|
||||||
|
PsiElement(INTEGER_LITERAL)('3')
|
||||||
|
PsiWhiteSpace('\n')
|
||||||
|
PsiElement(RBRACE)('}')
|
||||||
|
PsiWhiteSpace('\n\n')
|
||||||
|
CLASS
|
||||||
|
PsiElement(class)('class')
|
||||||
|
PsiWhiteSpace(' ')
|
||||||
|
PsiElement(IDENTIFIER)('A')
|
||||||
|
PsiWhiteSpace(' ')
|
||||||
|
CLASS_BODY
|
||||||
|
PsiElement(LBRACE)('{')
|
||||||
|
PsiWhiteSpace('\n ')
|
||||||
|
PROPERTY
|
||||||
|
PsiElement(val)('val')
|
||||||
|
PsiWhiteSpace(' ')
|
||||||
|
PsiElement(IDENTIFIER)('z')
|
||||||
|
PsiWhiteSpace(' ')
|
||||||
|
PsiElement(EQ)('=')
|
||||||
|
PsiWhiteSpace(' ')
|
||||||
|
BINARY_EXPRESSION
|
||||||
|
NULL
|
||||||
|
PsiElement(null)('null')
|
||||||
|
PsiWhiteSpace(' ')
|
||||||
|
OPERATION_REFERENCE
|
||||||
|
PsiElement(ELVIS)('?:')
|
||||||
|
PsiErrorElement:Expecting an element
|
||||||
|
<empty list>
|
||||||
|
PsiWhiteSpace('\n ')
|
||||||
|
PROPERTY
|
||||||
|
PsiElement(val)('val')
|
||||||
|
PsiWhiteSpace(' ')
|
||||||
|
PsiElement(IDENTIFIER)('x')
|
||||||
|
PsiWhiteSpace(' ')
|
||||||
|
PsiElement(EQ)('=')
|
||||||
|
PsiWhiteSpace(' ')
|
||||||
|
INTEGER_CONSTANT
|
||||||
|
PsiElement(INTEGER_LITERAL)('4')
|
||||||
|
PsiWhiteSpace('\n\n ')
|
||||||
|
PROPERTY
|
||||||
|
PsiElement(val)('val')
|
||||||
|
PsiWhiteSpace(' ')
|
||||||
|
PsiElement(IDENTIFIER)('y')
|
||||||
|
PsiWhiteSpace(' ')
|
||||||
|
PsiElement(EQ)('=')
|
||||||
|
PsiWhiteSpace(' ')
|
||||||
|
BINARY_EXPRESSION
|
||||||
|
NULL
|
||||||
|
PsiElement(null)('null')
|
||||||
|
PsiWhiteSpace(' ')
|
||||||
|
OPERATION_REFERENCE
|
||||||
|
PsiElement(ELVIS)('?:')
|
||||||
|
PsiErrorElement:Expecting an element
|
||||||
|
<empty list>
|
||||||
|
PsiWhiteSpace('\n ')
|
||||||
|
FUN
|
||||||
|
PsiElement(fun)('fun')
|
||||||
|
PsiWhiteSpace(' ')
|
||||||
|
PsiElement(IDENTIFIER)('baz')
|
||||||
|
VALUE_PARAMETER_LIST
|
||||||
|
PsiElement(LPAR)('(')
|
||||||
|
PsiElement(RPAR)(')')
|
||||||
|
PsiWhiteSpace(' ')
|
||||||
|
PsiElement(EQ)('=')
|
||||||
|
PsiWhiteSpace(' ')
|
||||||
|
INTEGER_CONSTANT
|
||||||
|
PsiElement(INTEGER_LITERAL)('5')
|
||||||
|
PsiWhiteSpace('\n\n ')
|
||||||
|
PROPERTY
|
||||||
|
PsiElement(val)('val')
|
||||||
|
PsiWhiteSpace(' ')
|
||||||
|
PsiElement(IDENTIFIER)('q')
|
||||||
|
PsiWhiteSpace(' ')
|
||||||
|
PsiElement(EQ)('=')
|
||||||
|
PsiWhiteSpace(' ')
|
||||||
|
BINARY_EXPRESSION
|
||||||
|
NULL
|
||||||
|
PsiElement(null)('null')
|
||||||
|
PsiWhiteSpace(' ')
|
||||||
|
OPERATION_REFERENCE
|
||||||
|
PsiElement(ELVIS)('?:')
|
||||||
|
PsiWhiteSpace('\n ')
|
||||||
|
FUN
|
||||||
|
PsiElement(fun)('fun')
|
||||||
|
PsiWhiteSpace(' ')
|
||||||
|
TYPE_REFERENCE
|
||||||
|
USER_TYPE
|
||||||
|
REFERENCE_EXPRESSION
|
||||||
|
PsiElement(IDENTIFIER)('String')
|
||||||
|
PsiElement(DOT)('.')
|
||||||
|
VALUE_PARAMETER_LIST
|
||||||
|
PsiElement(LPAR)('(')
|
||||||
|
PsiElement(RPAR)(')')
|
||||||
|
PsiWhiteSpace(' ')
|
||||||
|
PsiElement(EQ)('=')
|
||||||
|
PsiWhiteSpace(' ')
|
||||||
|
INTEGER_CONSTANT
|
||||||
|
PsiElement(INTEGER_LITERAL)('6')
|
||||||
|
PsiWhiteSpace('\n')
|
||||||
|
PsiElement(RBRACE)('}')
|
||||||
@@ -8723,6 +8723,18 @@ public class DiagnosticsTestGenerated extends AbstractDiagnosticsTest {
|
|||||||
doTest(fileName);
|
doTest(fileName);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@TestMetadata("declarationAfterDotSelectorExpected.kt")
|
||||||
|
public void testDeclarationAfterDotSelectorExpected() throws Exception {
|
||||||
|
String fileName = KotlinTestUtils.navigationMetadata("compiler/testData/diagnostics/tests/incompleteCode/diagnosticWithSyntaxError/declarationAfterDotSelectorExpected.kt");
|
||||||
|
doTest(fileName);
|
||||||
|
}
|
||||||
|
|
||||||
|
@TestMetadata("declarationAfterIncompleteElvis.kt")
|
||||||
|
public void testDeclarationAfterIncompleteElvis() throws Exception {
|
||||||
|
String fileName = KotlinTestUtils.navigationMetadata("compiler/testData/diagnostics/tests/incompleteCode/diagnosticWithSyntaxError/declarationAfterIncompleteElvis.kt");
|
||||||
|
doTest(fileName);
|
||||||
|
}
|
||||||
|
|
||||||
@TestMetadata("funEquals.kt")
|
@TestMetadata("funEquals.kt")
|
||||||
public void testFunEquals() throws Exception {
|
public void testFunEquals() throws Exception {
|
||||||
String fileName = KotlinTestUtils.navigationMetadata("compiler/testData/diagnostics/tests/incompleteCode/diagnosticWithSyntaxError/funEquals.kt");
|
String fileName = KotlinTestUtils.navigationMetadata("compiler/testData/diagnostics/tests/incompleteCode/diagnosticWithSyntaxError/funEquals.kt");
|
||||||
|
|||||||
@@ -1992,6 +1992,18 @@ public class ParsingTestGenerated extends AbstractParsingTest {
|
|||||||
doParsingTest(fileName);
|
doParsingTest(fileName);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@TestMetadata("DeclarationAfterDotSelectorExpected.kt")
|
||||||
|
public void testDeclarationAfterDotSelectorExpected() throws Exception {
|
||||||
|
String fileName = KotlinTestUtils.navigationMetadata("compiler/testData/psi/recovery/DeclarationAfterDotSelectorExpected.kt");
|
||||||
|
doParsingTest(fileName);
|
||||||
|
}
|
||||||
|
|
||||||
|
@TestMetadata("DeclarationAfterIncompleteElvis.kt")
|
||||||
|
public void testDeclarationAfterIncompleteElvis() throws Exception {
|
||||||
|
String fileName = KotlinTestUtils.navigationMetadata("compiler/testData/psi/recovery/DeclarationAfterIncompleteElvis.kt");
|
||||||
|
doParsingTest(fileName);
|
||||||
|
}
|
||||||
|
|
||||||
@TestMetadata("DoWhileWithEmptyCondition.kt")
|
@TestMetadata("DoWhileWithEmptyCondition.kt")
|
||||||
public void testDoWhileWithEmptyCondition() throws Exception {
|
public void testDoWhileWithEmptyCondition() throws Exception {
|
||||||
String fileName = KotlinTestUtils.navigationMetadata("compiler/testData/psi/recovery/DoWhileWithEmptyCondition.kt");
|
String fileName = KotlinTestUtils.navigationMetadata("compiler/testData/psi/recovery/DoWhileWithEmptyCondition.kt");
|
||||||
|
|||||||
Reference in New Issue
Block a user