From d058a07ce2356f1338cdd709bb17af00bc10d84b Mon Sep 17 00:00:00 2001 From: Denis Zharkov Date: Tue, 12 May 2015 14:45:51 +0300 Subject: [PATCH] Parsing: allow semicolon between declarations --- .../jetbrains/kotlin/parsing/JetParsing.java | 8 + .../psi/semicolonBetweenDeclarations.kt | 27 +++ .../psi/semicolonBetweenDeclarations.txt | 179 ++++++++++++++++++ .../parsing/JetParsingTestGenerated.java | 6 + 4 files changed, 220 insertions(+) create mode 100644 compiler/testData/psi/semicolonBetweenDeclarations.kt create mode 100644 compiler/testData/psi/semicolonBetweenDeclarations.txt diff --git a/compiler/frontend/src/org/jetbrains/kotlin/parsing/JetParsing.java b/compiler/frontend/src/org/jetbrains/kotlin/parsing/JetParsing.java index 0739ac47fdb..198e05caf25 100644 --- a/compiler/frontend/src/org/jetbrains/kotlin/parsing/JetParsing.java +++ b/compiler/frontend/src/org/jetbrains/kotlin/parsing/JetParsing.java @@ -371,6 +371,10 @@ public class JetParsing extends AbstractJetParsing { * ; */ private void parseTopLevelDeclaration() { + if (at(SEMICOLON)) { + advance(); // SEMICOLON + return; + } PsiBuilder.Marker decl = mark(); ModifierDetector detector = new ModifierDetector(); @@ -928,6 +932,10 @@ public class JetParsing extends AbstractJetParsing { * ; */ private void parseMemberDeclaration() { + if (at(SEMICOLON)) { + advance(); // SEMICOLON + return; + } PsiBuilder.Marker decl = mark(); ModifierDetector detector = new ModifierDetector(); diff --git a/compiler/testData/psi/semicolonBetweenDeclarations.kt b/compiler/testData/psi/semicolonBetweenDeclarations.kt new file mode 100644 index 00000000000..dac21fb18d5 --- /dev/null +++ b/compiler/testData/psi/semicolonBetweenDeclarations.kt @@ -0,0 +1,27 @@ +package foo; + +fun foo1() {}; +val x = 1;;;; +class A() { + val x = 1; + + fun foo() { + class A1; + val x = 1; + } + fun bar(); + + init {}; + + constructor() : super(); + + companion object {}; +}; + +fun foo; +val; +class B { + val; + init; + constructor; +} diff --git a/compiler/testData/psi/semicolonBetweenDeclarations.txt b/compiler/testData/psi/semicolonBetweenDeclarations.txt new file mode 100644 index 00000000000..258ecac9bda --- /dev/null +++ b/compiler/testData/psi/semicolonBetweenDeclarations.txt @@ -0,0 +1,179 @@ +JetFile: semicolonBetweenDeclarations.kt + PACKAGE_DIRECTIVE + PsiElement(package)('package') + PsiWhiteSpace(' ') + REFERENCE_EXPRESSION + PsiElement(IDENTIFIER)('foo') + PsiElement(SEMICOLON)(';') + PsiWhiteSpace('\n\n') + FUN + PsiElement(fun)('fun') + PsiWhiteSpace(' ') + PsiElement(IDENTIFIER)('foo1') + VALUE_PARAMETER_LIST + PsiElement(LPAR)('(') + PsiElement(RPAR)(')') + PsiWhiteSpace(' ') + BLOCK + PsiElement(LBRACE)('{') + PsiElement(RBRACE)('}') + PsiElement(SEMICOLON)(';') + PsiWhiteSpace('\n') + PROPERTY + PsiElement(val)('val') + PsiWhiteSpace(' ') + PsiElement(IDENTIFIER)('x') + PsiWhiteSpace(' ') + PsiElement(EQ)('=') + PsiWhiteSpace(' ') + INTEGER_CONSTANT + PsiElement(INTEGER_LITERAL)('1') + PsiElement(SEMICOLON)(';') + PsiElement(SEMICOLON)(';') + PsiElement(SEMICOLON)(';') + PsiElement(SEMICOLON)(';') + PsiWhiteSpace('\n') + CLASS + PsiElement(class)('class') + PsiWhiteSpace(' ') + PsiElement(IDENTIFIER)('A') + PRIMARY_CONSTRUCTOR + VALUE_PARAMETER_LIST + PsiElement(LPAR)('(') + PsiElement(RPAR)(')') + PsiWhiteSpace(' ') + CLASS_BODY + PsiElement(LBRACE)('{') + PsiWhiteSpace('\n ') + PROPERTY + PsiElement(val)('val') + PsiWhiteSpace(' ') + PsiElement(IDENTIFIER)('x') + PsiWhiteSpace(' ') + PsiElement(EQ)('=') + PsiWhiteSpace(' ') + INTEGER_CONSTANT + PsiElement(INTEGER_LITERAL)('1') + PsiElement(SEMICOLON)(';') + PsiWhiteSpace('\n\n ') + FUN + PsiElement(fun)('fun') + PsiWhiteSpace(' ') + PsiElement(IDENTIFIER)('foo') + VALUE_PARAMETER_LIST + PsiElement(LPAR)('(') + PsiElement(RPAR)(')') + PsiWhiteSpace(' ') + BLOCK + PsiElement(LBRACE)('{') + PsiWhiteSpace('\n ') + CLASS + PsiElement(class)('class') + PsiWhiteSpace(' ') + PsiElement(IDENTIFIER)('A1') + PsiElement(SEMICOLON)(';') + PsiWhiteSpace('\n ') + PROPERTY + PsiElement(val)('val') + PsiWhiteSpace(' ') + PsiElement(IDENTIFIER)('x') + PsiWhiteSpace(' ') + PsiElement(EQ)('=') + PsiWhiteSpace(' ') + INTEGER_CONSTANT + PsiElement(INTEGER_LITERAL)('1') + PsiElement(SEMICOLON)(';') + PsiWhiteSpace('\n ') + PsiElement(RBRACE)('}') + PsiWhiteSpace('\n ') + FUN + PsiElement(fun)('fun') + PsiWhiteSpace(' ') + PsiElement(IDENTIFIER)('bar') + VALUE_PARAMETER_LIST + PsiElement(LPAR)('(') + PsiElement(RPAR)(')') + PsiElement(SEMICOLON)(';') + PsiWhiteSpace('\n\n ') + ANONYMOUS_INITIALIZER + PsiElement(init)('init') + PsiWhiteSpace(' ') + BLOCK + PsiElement(LBRACE)('{') + PsiElement(RBRACE)('}') + PsiElement(SEMICOLON)(';') + PsiWhiteSpace('\n\n ') + SECONDARY_CONSTRUCTOR + PsiElement(constructor)('constructor') + VALUE_PARAMETER_LIST + PsiElement(LPAR)('(') + PsiElement(RPAR)(')') + PsiWhiteSpace(' ') + PsiElement(COLON)(':') + PsiWhiteSpace(' ') + CONSTRUCTOR_DELEGATION_CALL + CONSTRUCTOR_DELEGATION_REFERENCE + PsiElement(super)('super') + VALUE_ARGUMENT_LIST + PsiElement(LPAR)('(') + PsiElement(RPAR)(')') + PsiElement(SEMICOLON)(';') + PsiWhiteSpace('\n\n ') + OBJECT_DECLARATION + MODIFIER_LIST + PsiElement(companion)('companion') + PsiWhiteSpace(' ') + PsiElement(object)('object') + PsiWhiteSpace(' ') + CLASS_BODY + PsiElement(LBRACE)('{') + PsiElement(RBRACE)('}') + PsiElement(SEMICOLON)(';') + PsiWhiteSpace('\n') + PsiElement(RBRACE)('}') + PsiElement(SEMICOLON)(';') + PsiWhiteSpace('\n\n') + FUN + PsiElement(fun)('fun') + PsiWhiteSpace(' ') + PsiElement(IDENTIFIER)('foo') + PsiErrorElement:Expecting '(' + + PsiElement(SEMICOLON)(';') + PsiWhiteSpace('\n') + PROPERTY + PsiElement(val)('val') + PsiErrorElement:Expecting property name or receiver type + + PsiElement(SEMICOLON)(';') + PsiWhiteSpace('\n') + CLASS + PsiElement(class)('class') + PsiWhiteSpace(' ') + PsiElement(IDENTIFIER)('B') + PsiWhiteSpace(' ') + CLASS_BODY + PsiElement(LBRACE)('{') + PsiWhiteSpace('\n ') + PROPERTY + PsiElement(val)('val') + PsiErrorElement:Expecting property name or receiver type + + PsiElement(SEMICOLON)(';') + PsiWhiteSpace('\n ') + ANONYMOUS_INITIALIZER + PsiElement(init)('init') + PsiErrorElement:Expecting '{' after 'init' + + PsiElement(SEMICOLON)(';') + PsiWhiteSpace('\n ') + SECONDARY_CONSTRUCTOR + PsiElement(constructor)('constructor') + PsiErrorElement:Expecting '(' + + CONSTRUCTOR_DELEGATION_CALL + CONSTRUCTOR_DELEGATION_REFERENCE + + PsiElement(SEMICOLON)(';') + PsiWhiteSpace('\n') + PsiElement(RBRACE)('}') \ No newline at end of file diff --git a/compiler/tests/org/jetbrains/kotlin/parsing/JetParsingTestGenerated.java b/compiler/tests/org/jetbrains/kotlin/parsing/JetParsingTestGenerated.java index 551f31cd816..cc0f709acc2 100644 --- a/compiler/tests/org/jetbrains/kotlin/parsing/JetParsingTestGenerated.java +++ b/compiler/tests/org/jetbrains/kotlin/parsing/JetParsingTestGenerated.java @@ -565,6 +565,12 @@ public class JetParsingTestGenerated extends AbstractJetParsingTest { doParsingTest(fileName); } + @TestMetadata("semicolonBetweenDeclarations.kt") + public void testSemicolonBetweenDeclarations() throws Exception { + String fileName = JetTestUtils.navigationMetadata("compiler/testData/psi/semicolonBetweenDeclarations.kt"); + doParsingTest(fileName); + } + @TestMetadata("SimpleClassMembers.kt") public void testSimpleClassMembers() throws Exception { String fileName = JetTestUtils.navigationMetadata("compiler/testData/psi/SimpleClassMembers.kt");