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:
Denis Zharkov
2016-07-13 18:32:47 +03:00
parent 06a659e6e7
commit 4725dd3028
14 changed files with 623 additions and 30 deletions
@@ -21,6 +21,7 @@ import com.intellij.lang.PsiBuilder;
import com.intellij.psi.tree.IElementType;
import com.intellij.psi.tree.TokenSet;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
import org.jetbrains.kotlin.KtNodeType;
import org.jetbrains.kotlin.KtNodeTypes;
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 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) {
ImmutableMap.Builder<String, KtToken> builder = ImmutableMap.builder();
for (IElementType token : tokens.getTypes()) {
@@ -298,8 +302,6 @@ public class KotlinExpressionParsing extends AbstractKotlinParsing {
* see the precedence table
*/
private void parseBinaryExpression(Precedence precedence) {
// System.out.println(precedence.name() + " at " + myBuilder.getTokenText());
PsiBuilder.Marker expression = mark();
precedence.parseHigherPrecedence(this);
@@ -331,10 +333,8 @@ public class KotlinExpressionParsing extends AbstractKotlinParsing {
* operation? prefixExpression
*/
private void parsePrefixExpression() {
// System.out.println("pre at " + myBuilder.getTokenText());
if (at(AT)) {
if (!parseLocalDeclaration()) {
if (!parseLocalDeclaration(/* rollbackIfDefinitelyNotExpression = */ false)) {
PsiBuilder.Marker expression = mark();
myKotlinParsing.parseAnnotations(DEFAULT);
parsePrefixExpression();
@@ -454,7 +454,7 @@ public class KotlinExpressionParsing extends AbstractKotlinParsing {
expression = mark();
}
parseCallExpression();
parseSelectorCallExpression();
if (firstExpressionParsed) {
expression.done(expressionType);
@@ -515,7 +515,7 @@ public class KotlinExpressionParsing extends AbstractKotlinParsing {
/*
* atomicExpression typeParameters? valueParameters? functionLiteral*
*/
private void parseCallExpression() {
private void parseSelectorCallExpression() {
PsiBuilder.Marker mark = mark();
parseAtomicExpression();
if (!myBuilder.newlineBeforeCurrentToken() && parseCallSuffix()) {
@@ -624,8 +624,6 @@ public class KotlinExpressionParsing extends AbstractKotlinParsing {
* ;
*/
private boolean parseAtomicExpression() {
// System.out.println("atom at " + myBuilder.getTokenText());
boolean ok = true;
if (at(LPAR)) {
@@ -670,9 +668,9 @@ public class KotlinExpressionParsing extends AbstractKotlinParsing {
else if (at(DO_KEYWORD)) {
parseDoWhile();
}
else if (atSet(CLASS_KEYWORD, INTERFACE_KEYWORD, FUN_KEYWORD, VAL_KEYWORD,
VAR_KEYWORD, TYPE_ALIAS_KEYWORD)) {
parseLocalDeclaration();
else if (atSet(LOCAL_DECLARATION_FIRST) &&
parseLocalDeclaration(/* rollbackIfDefinitelyNotExpression = */ myBuilder.newlineBeforeCurrentToken())) {
// declaration was parsed, do nothing
}
else if (at(IDENTIFIER)) {
parseSimpleNameExpression();
@@ -1018,12 +1016,12 @@ public class KotlinExpressionParsing extends AbstractKotlinParsing {
/*
* modifiers declarationRest
*/
private boolean parseLocalDeclaration() {
private boolean parseLocalDeclaration(boolean rollbackIfDefinitelyNotExpression) {
PsiBuilder.Marker decl = mark();
KotlinParsing.ModifierDetector detector = new KotlinParsing.ModifierDetector();
myKotlinParsing.parseModifierList(detector, DEFAULT, TokenSet.EMPTY);
IElementType declType = parseLocalDeclarationRest(detector.isEnumDetected());
IElementType declType = parseLocalDeclarationRest(detector.isEnumDetected(), rollbackIfDefinitelyNotExpression);
if (declType != null) {
// 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) {
if (!parseLocalDeclaration()) {
if (!parseLocalDeclaration(/* rollbackIfDefinitelyNotExpression = */false)) {
if (!atSet(EXPRESSION_FIRST)) {
errorAndAdvance("Expecting a statement");
}
@@ -1245,9 +1243,17 @@ public class KotlinExpressionParsing extends AbstractKotlinParsing {
* : object
* ;
*/
private IElementType parseLocalDeclarationRest(boolean isEnum) {
@Nullable
private IElementType parseLocalDeclarationRest(boolean isEnum, boolean failIfDefinitelyNotExpression) {
IElementType keywordToken = tt();
IElementType declType = null;
if (failIfDefinitelyNotExpression) {
if (keywordToken != FUN_KEYWORD) return null;
return myKotlinParsing.parseFunction(/* failIfIdentifierExists = */ true);
}
if (keywordToken == CLASS_KEYWORD || keywordToken == INTERFACE_KEYWORD) {
declType = myKotlinParsing.parseClass(isEnum);
}
@@ -21,6 +21,7 @@ import com.intellij.lang.WhitespacesBinders;
import com.intellij.openapi.diagnostic.Logger;
import com.intellij.psi.tree.IElementType;
import com.intellij.psi.tree.TokenSet;
import org.jetbrains.annotations.Contract;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
import org.jetbrains.kotlin.lexer.KtKeywordToken;
@@ -1444,6 +1445,11 @@ public class KotlinParsing extends AbstractKotlinParsing {
return accessorKind;
}
@NotNull
IElementType parseFunction() {
return parseFunction(false);
}
/*
* function
* : modifiers "fun" typeParameters?
@@ -1454,7 +1460,8 @@ public class KotlinParsing extends AbstractKotlinParsing {
* functionBody?
* ;
*/
IElementType parseFunction() {
@Contract("false -> !null")
IElementType parseFunction(boolean failIfIdentifierExists) {
assert _at(FUN_KEYWORD);
advance(); // FUN_KEYWORD
@@ -1476,6 +1483,11 @@ public class KotlinParsing extends AbstractKotlinParsing {
TokenSet functionNameFollow = TokenSet.create(LT, LPAR, RPAR, COLON, EQ);
boolean receiverFound = parseReceiverType("function", functionNameFollow);
if (at(IDENTIFIER) && failIfIdentifierExists) {
myBuilder.restoreJoiningComplexTokensState();
return null;
}
// function as expression has no name
parseFunctionOrPropertyName(receiverFound, "function", functionNameFollow, /*nameRequired = */ false);
@@ -1598,15 +1610,15 @@ public class KotlinParsing extends AbstractKotlinParsing {
/*
* IDENTIFIER
*/
private void parseFunctionOrPropertyName(boolean receiverFound, String title, TokenSet nameFollow, boolean nameRequired) {
if (!nameRequired && atSet(nameFollow)) return; // no name
private boolean parseFunctionOrPropertyName(boolean receiverFound, String title, TokenSet nameFollow, boolean nameRequired) {
if (!nameRequired && atSet(nameFollow)) return true; // no name
TokenSet recoverySet = TokenSet.orSet(nameFollow, TokenSet.create(LBRACE, RBRACE), TOP_LEVEL_DECLARATION_FIRST);
if (!receiverFound) {
expect(IDENTIFIER, "Expecting " + title + " name or receiver type", recoverySet);
return expect(IDENTIFIER, "Expecting " + title + " name or receiver type", recoverySet);
}
else {
expect(IDENTIFIER, "Expecting " + title + " name", recoverySet);
return expect(IDENTIFIER, "Expecting " + title + " name", recoverySet);
}
}
@@ -12,18 +12,18 @@ fun test() {
val x1 =
if (1 == 1)
// TODO: Diagnostic content could be better
<!EXPECTED_TYPE_MISMATCH(\(\) -> Int)!>fun named4(): Int {return 1}<!>
else
<!EXPECTED_TYPE_MISMATCH!>fun named5() = 1<!>
<!SYNTAX!><!>fun named4(): Int {return 1}
<!SYNTAX!>else<!>
fun named5() = 1
val x2 =
if (1 == 1) {
<!EXPECTED_TYPE_MISMATCH!>fun named6(): Int {
fun named6(): Int {
return 1
}<!>
}
}
else
<!EXPECTED_TYPE_MISMATCH!>fun named7() = 1<!>
<!SYNTAX!><!>fun named7() = 1
val x3 = when (1) {
0 -> <!EXPECTED_TYPE_MISMATCH!>fun named8(): Int {return 1}<!>
@@ -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
}
@@ -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
}
@@ -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
}
@@ -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
}
@@ -1,4 +1,4 @@
fun foo(s: String) {
s.
<!DECLARATION_IN_ILLEGAL_CONTEXT, ILLEGAL_SELECTOR!>val b = 42<!>
}
s.<!SYNTAX!><!>
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);
}
@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")
public void testFunEquals() throws Exception {
String fileName = KotlinTestUtils.navigationMetadata("compiler/testData/diagnostics/tests/incompleteCode/diagnosticWithSyntaxError/funEquals.kt");
@@ -1992,6 +1992,18 @@ public class ParsingTestGenerated extends AbstractParsingTest {
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")
public void testDoWhileWithEmptyCondition() throws Exception {
String fileName = KotlinTestUtils.navigationMetadata("compiler/testData/psi/recovery/DoWhileWithEmptyCondition.kt");