Script refactoring, parser: wrap statements in script as if they are init blocks of a class

This commit is contained in:
Pavel V. Talanov
2015-11-17 15:03:21 +03:00
parent e45585be21
commit daa1a08213
9 changed files with 154 additions and 116 deletions
@@ -1181,13 +1181,21 @@ public class KotlinExpressionParsing extends AbstractKotlinParsing {
* : SEMI* statement{SEMI+} SEMI*
*/
public void parseStatements() {
parseStatements(false);
}
/*
* expressions
* : SEMI* statement{SEMI+} SEMI*
*/
public void parseStatements(boolean isScriptTopLevel) {
while (at(SEMICOLON)) advance(); // SEMICOLON
while (!eof() && !at(RBRACE)) {
if (!atSet(STATEMENT_FIRST)) {
errorAndAdvance("Expecting an element");
}
if (atSet(STATEMENT_FIRST)) {
parseStatement();
parseStatement(isScriptTopLevel);
}
if (at(SEMICOLON)) {
while (at(SEMICOLON)) advance(); // SEMICOLON
@@ -1214,11 +1222,16 @@ public class KotlinExpressionParsing extends AbstractKotlinParsing {
* : declaration
* ;
*/
private void parseStatement() {
private void parseStatement(boolean isScriptTopLevel) {
if (!parseLocalDeclaration()) {
if (!atSet(EXPRESSION_FIRST)) {
errorAndAdvance("Expecting a statement");
}
else if (isScriptTopLevel){
PsiBuilder.Marker scriptInitializer = mark();
parseExpression();
scriptInitializer.done(ANONYMOUS_INITIALIZER);
}
else {
parseExpression();
}
@@ -160,7 +160,7 @@ public class KotlinParsing extends AbstractKotlinParsing {
PsiBuilder.Marker blockMarker = mark();
myExpressionParsing.parseStatements();
myExpressionParsing.parseStatements(/*isScriptTopLevel = */true);
checkForUnexpectedSymbols();
@@ -18,6 +18,7 @@ package org.jetbrains.kotlin.psi;
import com.intellij.lang.ASTNode;
import com.intellij.psi.PsiElement;
import com.intellij.psi.util.PsiTreeUtil;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
import org.jetbrains.kotlin.lexer.KtTokens;
@@ -59,4 +60,15 @@ public class KtClassInitializer extends KtDeclarationStub<KotlinPlaceHolderStub<
public PsiElement getInitKeyword() {
return findChildByType(KtTokens.INIT_KEYWORD);
}
@NotNull
public KtDeclaration getContainingDeclaration() {
KtClassOrObject classOrObject = PsiTreeUtil.getParentOfType(this, KtClassOrObject.class, true);
if (classOrObject != null) {
return classOrObject;
}
KtScript type = PsiTreeUtil.getParentOfType(this, KtScript.class, true);
assert type != null : "Should only be present in class, object or script";
return type;
}
}
+69 -67
View File
@@ -58,71 +58,73 @@ JetFile: ComplexScript.kts
PsiWhiteSpace('\n')
PsiElement(RBRACE)('}')
PsiWhiteSpace('\n\n')
IF
PsiElement(if)('if')
PsiWhiteSpace(' ')
PsiElement(LPAR)('(')
CONDITION
BINARY_EXPRESSION
DOT_QUALIFIED_EXPRESSION
REFERENCE_EXPRESSION
PsiElement(IDENTIFIER)('args')
PsiElement(DOT)('.')
REFERENCE_EXPRESSION
PsiElement(IDENTIFIER)('length')
PsiWhiteSpace(' ')
OPERATION_REFERENCE
PsiElement(EQEQ)('==')
PsiWhiteSpace(' ')
INTEGER_CONSTANT
PsiElement(INTEGER_LITERAL)('0')
PsiElement(RPAR)(')')
PsiWhiteSpace(' ')
THEN
BLOCK
PsiElement(LBRACE)('{')
PsiWhiteSpace('\n ')
CALL_EXPRESSION
REFERENCE_EXPRESSION
PsiElement(IDENTIFIER)('die')
VALUE_ARGUMENT_LIST
PsiElement(LPAR)('(')
VALUE_ARGUMENT
STRING_TEMPLATE
PsiElement(OPEN_QUOTE)('"')
LITERAL_STRING_TEMPLATE_ENTRY
PsiElement(REGULAR_STRING_PART)('Need arguments')
PsiElement(CLOSING_QUOTE)('"')
PsiElement(RPAR)(')')
PsiWhiteSpace('\n')
PsiElement(RBRACE)('}')
ANONYMOUS_INITIALIZER
IF
PsiElement(if)('if')
PsiWhiteSpace(' ')
PsiElement(LPAR)('(')
CONDITION
BINARY_EXPRESSION
DOT_QUALIFIED_EXPRESSION
REFERENCE_EXPRESSION
PsiElement(IDENTIFIER)('args')
PsiElement(DOT)('.')
REFERENCE_EXPRESSION
PsiElement(IDENTIFIER)('length')
PsiWhiteSpace(' ')
OPERATION_REFERENCE
PsiElement(EQEQ)('==')
PsiWhiteSpace(' ')
INTEGER_CONSTANT
PsiElement(INTEGER_LITERAL)('0')
PsiElement(RPAR)(')')
PsiWhiteSpace(' ')
THEN
BLOCK
PsiElement(LBRACE)('{')
PsiWhiteSpace('\n ')
CALL_EXPRESSION
REFERENCE_EXPRESSION
PsiElement(IDENTIFIER)('die')
VALUE_ARGUMENT_LIST
PsiElement(LPAR)('(')
VALUE_ARGUMENT
STRING_TEMPLATE
PsiElement(OPEN_QUOTE)('"')
LITERAL_STRING_TEMPLATE_ENTRY
PsiElement(REGULAR_STRING_PART)('Need arguments')
PsiElement(CLOSING_QUOTE)('"')
PsiElement(RPAR)(')')
PsiWhiteSpace('\n')
PsiElement(RBRACE)('}')
PsiWhiteSpace('\n\n')
FOR
PsiElement(for)('for')
PsiWhiteSpace(' ')
PsiElement(LPAR)('(')
VALUE_PARAMETER
PsiElement(IDENTIFIER)('arg')
PsiWhiteSpace(' ')
PsiElement(in)('in')
PsiWhiteSpace(' ')
LOOP_RANGE
REFERENCE_EXPRESSION
PsiElement(IDENTIFIER)('args')
PsiElement(RPAR)(')')
PsiWhiteSpace(' ')
BODY
BLOCK
PsiElement(LBRACE)('{')
PsiWhiteSpace('\n ')
CALL_EXPRESSION
REFERENCE_EXPRESSION
PsiElement(IDENTIFIER)('println')
VALUE_ARGUMENT_LIST
PsiElement(LPAR)('(')
VALUE_ARGUMENT
REFERENCE_EXPRESSION
PsiElement(IDENTIFIER)('arg')
PsiElement(RPAR)(')')
PsiWhiteSpace('\n')
PsiElement(RBRACE)('}')
ANONYMOUS_INITIALIZER
FOR
PsiElement(for)('for')
PsiWhiteSpace(' ')
PsiElement(LPAR)('(')
VALUE_PARAMETER
PsiElement(IDENTIFIER)('arg')
PsiWhiteSpace(' ')
PsiElement(in)('in')
PsiWhiteSpace(' ')
LOOP_RANGE
REFERENCE_EXPRESSION
PsiElement(IDENTIFIER)('args')
PsiElement(RPAR)(')')
PsiWhiteSpace(' ')
BODY
BLOCK
PsiElement(LBRACE)('{')
PsiWhiteSpace('\n ')
CALL_EXPRESSION
REFERENCE_EXPRESSION
PsiElement(IDENTIFIER)('println')
VALUE_ARGUMENT_LIST
PsiElement(LPAR)('(')
VALUE_ARGUMENT
REFERENCE_EXPRESSION
PsiElement(IDENTIFIER)('arg')
PsiElement(RPAR)(')')
PsiWhiteSpace('\n')
PsiElement(RBRACE)('}')
+10 -9
View File
@@ -7,12 +7,13 @@ JetFile: Shebang.kts
PsiWhiteSpace('\n\n')
SCRIPT
BLOCK
CALL_EXPRESSION
REFERENCE_EXPRESSION
PsiElement(IDENTIFIER)('println')
VALUE_ARGUMENT_LIST
PsiElement(LPAR)('(')
VALUE_ARGUMENT
REFERENCE_EXPRESSION
PsiElement(IDENTIFIER)('args')
PsiElement(RPAR)(')')
ANONYMOUS_INITIALIZER
CALL_EXPRESSION
REFERENCE_EXPRESSION
PsiElement(IDENTIFIER)('println')
VALUE_ARGUMENT_LIST
PsiElement(LPAR)('(')
VALUE_ARGUMENT
REFERENCE_EXPRESSION
PsiElement(IDENTIFIER)('args')
PsiElement(RPAR)(')')
+20 -18
View File
@@ -5,30 +5,32 @@ JetFile: ShebangIncorrect.kts
<empty list>
SCRIPT
BLOCK
CALL_EXPRESSION
REFERENCE_EXPRESSION
PsiElement(IDENTIFIER)('println')
VALUE_ARGUMENT_LIST
PsiElement(LPAR)('(')
VALUE_ARGUMENT
INTEGER_CONSTANT
PsiElement(INTEGER_LITERAL)('1')
PsiElement(RPAR)(')')
ANONYMOUS_INITIALIZER
CALL_EXPRESSION
REFERENCE_EXPRESSION
PsiElement(IDENTIFIER)('println')
VALUE_ARGUMENT_LIST
PsiElement(LPAR)('(')
VALUE_ARGUMENT
INTEGER_CONSTANT
PsiElement(INTEGER_LITERAL)('1')
PsiElement(RPAR)(')')
PsiElement(SEMICOLON)(';')
PsiWhiteSpace(' ')
PsiErrorElement:Expecting an element
PsiElement(HASH)('#')
BINARY_EXPRESSION
PREFIX_EXPRESSION
ANONYMOUS_INITIALIZER
BINARY_EXPRESSION
PREFIX_EXPRESSION
OPERATION_REFERENCE
PsiElement(EXCL)('!')
PsiErrorElement:Expecting an element
PsiElement(DIV)('/')
OPERATION_REFERENCE
PsiElement(EXCL)('!')
PsiElement(IDENTIFIER)('usr')
PsiWhiteSpace('\n\n')
PsiErrorElement:Expecting an element
PsiElement(DIV)('/')
OPERATION_REFERENCE
PsiElement(IDENTIFIER)('usr')
PsiWhiteSpace('\n\n')
PsiErrorElement:Expecting an element
PsiElement(HASH)('#')
PsiElement(HASH)('#')
PsiErrorElement:Unexpected tokens (use ';' to separate expressions on the same line)
PsiElement(EXCL)('!')
PsiElement(DIV)('/')
+10 -9
View File
@@ -5,12 +5,13 @@ JetFile: SimpleScript.kts
<empty list>
SCRIPT
BLOCK
CALL_EXPRESSION
REFERENCE_EXPRESSION
PsiElement(IDENTIFIER)('println')
VALUE_ARGUMENT_LIST
PsiElement(LPAR)('(')
VALUE_ARGUMENT
INTEGER_CONSTANT
PsiElement(INTEGER_LITERAL)('1')
PsiElement(RPAR)(')')
ANONYMOUS_INITIALIZER
CALL_EXPRESSION
REFERENCE_EXPRESSION
PsiElement(IDENTIFIER)('println')
VALUE_ARGUMENT_LIST
PsiElement(LPAR)('(')
VALUE_ARGUMENT
INTEGER_CONSTANT
PsiElement(INTEGER_LITERAL)('1')
PsiElement(RPAR)(')')
+11 -10
View File
@@ -5,15 +5,16 @@ JetFile: unexpectedSymbol.kts
<empty list>
SCRIPT
BLOCK
CALL_EXPRESSION
REFERENCE_EXPRESSION
PsiElement(IDENTIFIER)('println')
VALUE_ARGUMENT_LIST
PsiElement(LPAR)('(')
VALUE_ARGUMENT
INTEGER_CONSTANT
PsiElement(INTEGER_LITERAL)('1')
PsiElement(RPAR)(')')
ANONYMOUS_INITIALIZER
CALL_EXPRESSION
REFERENCE_EXPRESSION
PsiElement(IDENTIFIER)('println')
VALUE_ARGUMENT_LIST
PsiElement(LPAR)('(')
VALUE_ARGUMENT
INTEGER_CONSTANT
PsiElement(INTEGER_LITERAL)('1')
PsiElement(RPAR)(')')
PsiWhiteSpace('\n')
PsiErrorElement:unexpected symbol
PsiElement(RBRACE)('}')
PsiElement(RBRACE)('}')
@@ -41,6 +41,12 @@ public abstract class AbstractParsingTest extends ParsingTestCase {
System.setProperty("idea.platform.prefix", "Idea");
}
@Override
protected void setUp() throws Exception {
super.setUp();
getProject().registerService(KotlinScriptDefinitionProvider.class);
}
@Override
protected String getTestDataPath() {
return KotlinTestUtils.getHomeDirectory();