Script refactoring, parser: wrap statements in script as if they are init blocks of a class
This commit is contained in:
@@ -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
@@ -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
@@ -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
@@ -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
@@ -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
@@ -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();
|
||||
|
||||
Reference in New Issue
Block a user