FIC: Parse fun keyword in front of interface as a modifier
This commit is contained in:
@@ -57,7 +57,7 @@ public interface KtTokens {
|
||||
KtKeywordToken SUPER_KEYWORD = KtKeywordToken.keyword("super");
|
||||
KtKeywordToken VAL_KEYWORD = KtKeywordToken.keyword("val");
|
||||
KtKeywordToken VAR_KEYWORD = KtKeywordToken.keyword("var");
|
||||
KtKeywordToken FUN_KEYWORD = KtKeywordToken.keyword("fun");
|
||||
KtModifierKeywordToken FUN_KEYWORD = KtModifierKeywordToken.keywordModifier("fun");
|
||||
KtKeywordToken FOR_KEYWORD = KtKeywordToken.keyword("for");
|
||||
KtKeywordToken NULL_KEYWORD = KtKeywordToken.keyword("null");
|
||||
KtKeywordToken TRUE_KEYWORD = KtKeywordToken.keyword("true");
|
||||
@@ -229,7 +229,7 @@ public interface KtTokens {
|
||||
REIFIED_KEYWORD, COMPANION_KEYWORD, SEALED_KEYWORD, LATEINIT_KEYWORD,
|
||||
DATA_KEYWORD, INLINE_KEYWORD, NOINLINE_KEYWORD, TAILREC_KEYWORD, EXTERNAL_KEYWORD, ANNOTATION_KEYWORD, CROSSINLINE_KEYWORD,
|
||||
CONST_KEYWORD, OPERATOR_KEYWORD, INFIX_KEYWORD, SUSPEND_KEYWORD,
|
||||
HEADER_KEYWORD, IMPL_KEYWORD, EXPECT_KEYWORD, ACTUAL_KEYWORD
|
||||
HEADER_KEYWORD, IMPL_KEYWORD, EXPECT_KEYWORD, ACTUAL_KEYWORD, FUN_KEYWORD
|
||||
};
|
||||
|
||||
TokenSet MODIFIER_KEYWORDS = TokenSet.create(MODIFIER_KEYWORDS_ARRAY);
|
||||
|
||||
@@ -51,9 +51,15 @@ public class KotlinParsing extends AbstractKotlinParsing {
|
||||
private static final TokenSet TYPE_REF_FIRST = TokenSet.create(LBRACKET, IDENTIFIER, LPAR, HASH, DYNAMIC_KEYWORD);
|
||||
private static final TokenSet RECEIVER_TYPE_TERMINATORS = TokenSet.create(DOT, SAFE_ACCESS);
|
||||
private static final TokenSet VALUE_PARAMETER_FIRST =
|
||||
TokenSet.orSet(TokenSet.create(IDENTIFIER, LBRACKET, VAL_KEYWORD, VAR_KEYWORD), MODIFIER_KEYWORDS);
|
||||
TokenSet.orSet(
|
||||
TokenSet.create(IDENTIFIER, LBRACKET, VAL_KEYWORD, VAR_KEYWORD),
|
||||
TokenSet.andNot(MODIFIER_KEYWORDS, TokenSet.create(FUN_KEYWORD))
|
||||
);
|
||||
private static final TokenSet LAMBDA_VALUE_PARAMETER_FIRST =
|
||||
TokenSet.orSet(TokenSet.create(IDENTIFIER, LBRACKET), MODIFIER_KEYWORDS);
|
||||
TokenSet.orSet(
|
||||
TokenSet.create(IDENTIFIER, LBRACKET),
|
||||
TokenSet.andNot(MODIFIER_KEYWORDS, TokenSet.create(FUN_KEYWORD))
|
||||
);
|
||||
private static final TokenSet SOFT_KEYWORDS_AT_MEMBER_START = TokenSet.create(CONSTRUCTOR_KEYWORD, INIT_KEYWORD);
|
||||
private static final TokenSet ANNOTATION_TARGETS = TokenSet.create(
|
||||
FILE_KEYWORD, FIELD_KEYWORD, GET_KEYWORD, SET_KEYWORD, PROPERTY_KEYWORD,
|
||||
@@ -585,6 +591,12 @@ public class KotlinParsing extends AbstractKotlinParsing {
|
||||
|
||||
if (atSet(modifierKeywords)) {
|
||||
IElementType lookahead = lookahead(1);
|
||||
|
||||
if (at(FUN_KEYWORD) && lookahead != INTERFACE_KEYWORD) {
|
||||
marker.rollbackTo();
|
||||
return false;
|
||||
}
|
||||
|
||||
if (lookahead != null && !noModifiersBefore.contains(lookahead)) {
|
||||
IElementType tt = tt();
|
||||
if (tokenConsumer != null) {
|
||||
|
||||
+11
@@ -0,0 +1,11 @@
|
||||
interface fun Foo
|
||||
|
||||
fun private interface Foo
|
||||
|
||||
fun @Bar interface Foo
|
||||
|
||||
fun class Foo
|
||||
|
||||
fun abstract class Foo
|
||||
|
||||
fun object Foo
|
||||
@@ -0,0 +1,79 @@
|
||||
KtFile: kotlinFunInterface_ERR.kt
|
||||
PACKAGE_DIRECTIVE
|
||||
<empty list>
|
||||
IMPORT_LIST
|
||||
<empty list>
|
||||
CLASS
|
||||
PsiElement(interface)('interface')
|
||||
PsiErrorElement:Name expected
|
||||
<empty list>
|
||||
PsiWhiteSpace(' ')
|
||||
FUN
|
||||
PsiElement(fun)('fun')
|
||||
PsiWhiteSpace(' ')
|
||||
PsiElement(IDENTIFIER)('Foo')
|
||||
PsiErrorElement:Expecting '('
|
||||
<empty list>
|
||||
PsiWhiteSpace('\n\n')
|
||||
FUN
|
||||
PsiElement(fun)('fun')
|
||||
PsiWhiteSpace(' ')
|
||||
PsiElement(IDENTIFIER)('private')
|
||||
PsiErrorElement:Expecting '('
|
||||
<empty list>
|
||||
PsiWhiteSpace(' ')
|
||||
CLASS
|
||||
PsiElement(interface)('interface')
|
||||
PsiWhiteSpace(' ')
|
||||
PsiElement(IDENTIFIER)('Foo')
|
||||
PsiWhiteSpace('\n\n')
|
||||
FUN
|
||||
PsiElement(fun)('fun')
|
||||
PsiWhiteSpace(' ')
|
||||
PsiErrorElement:Annotations are not allowed in this position
|
||||
ANNOTATION_ENTRY
|
||||
PsiElement(AT)('@')
|
||||
CONSTRUCTOR_CALLEE
|
||||
TYPE_REFERENCE
|
||||
USER_TYPE
|
||||
REFERENCE_EXPRESSION
|
||||
PsiElement(IDENTIFIER)('Bar')
|
||||
PsiErrorElement:Expecting function name or receiver type
|
||||
<empty list>
|
||||
PsiWhiteSpace(' ')
|
||||
CLASS
|
||||
PsiElement(interface)('interface')
|
||||
PsiWhiteSpace(' ')
|
||||
PsiElement(IDENTIFIER)('Foo')
|
||||
PsiWhiteSpace('\n\n')
|
||||
FUN
|
||||
PsiElement(fun)('fun')
|
||||
PsiErrorElement:Expecting function name or receiver type
|
||||
<empty list>
|
||||
PsiWhiteSpace(' ')
|
||||
CLASS
|
||||
PsiElement(class)('class')
|
||||
PsiWhiteSpace(' ')
|
||||
PsiElement(IDENTIFIER)('Foo')
|
||||
PsiWhiteSpace('\n\n')
|
||||
FUN
|
||||
PsiElement(fun)('fun')
|
||||
PsiWhiteSpace(' ')
|
||||
PsiElement(IDENTIFIER)('abstract')
|
||||
PsiErrorElement:Expecting '('
|
||||
<empty list>
|
||||
PsiWhiteSpace(' ')
|
||||
CLASS
|
||||
PsiElement(class)('class')
|
||||
PsiWhiteSpace(' ')
|
||||
PsiElement(IDENTIFIER)('Foo')
|
||||
PsiWhiteSpace('\n\n')
|
||||
FUN
|
||||
PsiElement(fun)('fun')
|
||||
PsiErrorElement:Expecting function name or receiver type
|
||||
<empty list>
|
||||
PsiWhiteSpace(' ')
|
||||
OBJECT_DECLARATION
|
||||
PsiElement(object)('object')
|
||||
PsiWhiteSpace(' ')
|
||||
PsiElement(IDENTIFIER)('Foo')
|
||||
@@ -0,0 +1,17 @@
|
||||
fun interface Foo
|
||||
|
||||
fun interface Foo {
|
||||
fun invoke()
|
||||
}
|
||||
|
||||
private fun interface Foo
|
||||
|
||||
@Bar
|
||||
fun interface Foo
|
||||
|
||||
class TopLevel {
|
||||
fun interface Foo
|
||||
}
|
||||
|
||||
fun
|
||||
interface Foo
|
||||
@@ -0,0 +1,85 @@
|
||||
KtFile: validKotlinFunInterface.kt
|
||||
PACKAGE_DIRECTIVE
|
||||
<empty list>
|
||||
IMPORT_LIST
|
||||
<empty list>
|
||||
CLASS
|
||||
MODIFIER_LIST
|
||||
PsiElement(fun)('fun')
|
||||
PsiWhiteSpace(' ')
|
||||
PsiElement(interface)('interface')
|
||||
PsiWhiteSpace(' ')
|
||||
PsiElement(IDENTIFIER)('Foo')
|
||||
PsiWhiteSpace('\n\n')
|
||||
CLASS
|
||||
MODIFIER_LIST
|
||||
PsiElement(fun)('fun')
|
||||
PsiWhiteSpace(' ')
|
||||
PsiElement(interface)('interface')
|
||||
PsiWhiteSpace(' ')
|
||||
PsiElement(IDENTIFIER)('Foo')
|
||||
PsiWhiteSpace(' ')
|
||||
CLASS_BODY
|
||||
PsiElement(LBRACE)('{')
|
||||
PsiWhiteSpace('\n ')
|
||||
FUN
|
||||
PsiElement(fun)('fun')
|
||||
PsiWhiteSpace(' ')
|
||||
PsiElement(IDENTIFIER)('invoke')
|
||||
VALUE_PARAMETER_LIST
|
||||
PsiElement(LPAR)('(')
|
||||
PsiElement(RPAR)(')')
|
||||
PsiWhiteSpace('\n')
|
||||
PsiElement(RBRACE)('}')
|
||||
PsiWhiteSpace('\n\n')
|
||||
CLASS
|
||||
MODIFIER_LIST
|
||||
PsiElement(private)('private')
|
||||
PsiWhiteSpace(' ')
|
||||
PsiElement(fun)('fun')
|
||||
PsiWhiteSpace(' ')
|
||||
PsiElement(interface)('interface')
|
||||
PsiWhiteSpace(' ')
|
||||
PsiElement(IDENTIFIER)('Foo')
|
||||
PsiWhiteSpace('\n\n')
|
||||
CLASS
|
||||
MODIFIER_LIST
|
||||
ANNOTATION_ENTRY
|
||||
PsiElement(AT)('@')
|
||||
CONSTRUCTOR_CALLEE
|
||||
TYPE_REFERENCE
|
||||
USER_TYPE
|
||||
REFERENCE_EXPRESSION
|
||||
PsiElement(IDENTIFIER)('Bar')
|
||||
PsiWhiteSpace('\n')
|
||||
PsiElement(fun)('fun')
|
||||
PsiWhiteSpace(' ')
|
||||
PsiElement(interface)('interface')
|
||||
PsiWhiteSpace(' ')
|
||||
PsiElement(IDENTIFIER)('Foo')
|
||||
PsiWhiteSpace('\n\n')
|
||||
CLASS
|
||||
PsiElement(class)('class')
|
||||
PsiWhiteSpace(' ')
|
||||
PsiElement(IDENTIFIER)('TopLevel')
|
||||
PsiWhiteSpace(' ')
|
||||
CLASS_BODY
|
||||
PsiElement(LBRACE)('{')
|
||||
PsiWhiteSpace('\n ')
|
||||
CLASS
|
||||
MODIFIER_LIST
|
||||
PsiElement(fun)('fun')
|
||||
PsiWhiteSpace(' ')
|
||||
PsiElement(interface)('interface')
|
||||
PsiWhiteSpace(' ')
|
||||
PsiElement(IDENTIFIER)('Foo')
|
||||
PsiWhiteSpace('\n')
|
||||
PsiElement(RBRACE)('}')
|
||||
PsiWhiteSpace('\n\n')
|
||||
CLASS
|
||||
MODIFIER_LIST
|
||||
PsiElement(fun)('fun')
|
||||
PsiWhiteSpace('\n')
|
||||
PsiElement(interface)('interface')
|
||||
PsiWhiteSpace(' ')
|
||||
PsiElement(IDENTIFIER)('Foo')
|
||||
@@ -450,6 +450,11 @@ public class ParsingTestGenerated extends AbstractParsingTest {
|
||||
runTest("compiler/testData/psi/InterfaceWithEnumKeyword.kt");
|
||||
}
|
||||
|
||||
@TestMetadata("kotlinFunInterface_ERR.kt")
|
||||
public void testKotlinFunInterface_ERR() throws Exception {
|
||||
runTest("compiler/testData/psi/kotlinFunInterface_ERR.kt");
|
||||
}
|
||||
|
||||
@TestMetadata("Labels.kt")
|
||||
public void testLabels() throws Exception {
|
||||
runTest("compiler/testData/psi/Labels.kt");
|
||||
@@ -715,6 +720,11 @@ public class ParsingTestGenerated extends AbstractParsingTest {
|
||||
runTest("compiler/testData/psi/UnsignedLiteral.kt");
|
||||
}
|
||||
|
||||
@TestMetadata("validKotlinFunInterface.kt")
|
||||
public void testValidKotlinFunInterface() throws Exception {
|
||||
runTest("compiler/testData/psi/validKotlinFunInterface.kt");
|
||||
}
|
||||
|
||||
@TestMetadata("When.kt")
|
||||
public void testWhen() throws Exception {
|
||||
runTest("compiler/testData/psi/When.kt");
|
||||
|
||||
Reference in New Issue
Block a user