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*
|
* : SEMI* statement{SEMI+} SEMI*
|
||||||
*/
|
*/
|
||||||
public void parseStatements() {
|
public void parseStatements() {
|
||||||
|
parseStatements(false);
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* expressions
|
||||||
|
* : SEMI* statement{SEMI+} SEMI*
|
||||||
|
*/
|
||||||
|
public void parseStatements(boolean isScriptTopLevel) {
|
||||||
while (at(SEMICOLON)) advance(); // SEMICOLON
|
while (at(SEMICOLON)) advance(); // SEMICOLON
|
||||||
while (!eof() && !at(RBRACE)) {
|
while (!eof() && !at(RBRACE)) {
|
||||||
if (!atSet(STATEMENT_FIRST)) {
|
if (!atSet(STATEMENT_FIRST)) {
|
||||||
errorAndAdvance("Expecting an element");
|
errorAndAdvance("Expecting an element");
|
||||||
}
|
}
|
||||||
if (atSet(STATEMENT_FIRST)) {
|
if (atSet(STATEMENT_FIRST)) {
|
||||||
parseStatement();
|
parseStatement(isScriptTopLevel);
|
||||||
}
|
}
|
||||||
if (at(SEMICOLON)) {
|
if (at(SEMICOLON)) {
|
||||||
while (at(SEMICOLON)) advance(); // SEMICOLON
|
while (at(SEMICOLON)) advance(); // SEMICOLON
|
||||||
@@ -1214,11 +1222,16 @@ public class KotlinExpressionParsing extends AbstractKotlinParsing {
|
|||||||
* : declaration
|
* : declaration
|
||||||
* ;
|
* ;
|
||||||
*/
|
*/
|
||||||
private void parseStatement() {
|
private void parseStatement(boolean isScriptTopLevel) {
|
||||||
if (!parseLocalDeclaration()) {
|
if (!parseLocalDeclaration()) {
|
||||||
if (!atSet(EXPRESSION_FIRST)) {
|
if (!atSet(EXPRESSION_FIRST)) {
|
||||||
errorAndAdvance("Expecting a statement");
|
errorAndAdvance("Expecting a statement");
|
||||||
}
|
}
|
||||||
|
else if (isScriptTopLevel){
|
||||||
|
PsiBuilder.Marker scriptInitializer = mark();
|
||||||
|
parseExpression();
|
||||||
|
scriptInitializer.done(ANONYMOUS_INITIALIZER);
|
||||||
|
}
|
||||||
else {
|
else {
|
||||||
parseExpression();
|
parseExpression();
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -160,7 +160,7 @@ public class KotlinParsing extends AbstractKotlinParsing {
|
|||||||
|
|
||||||
PsiBuilder.Marker blockMarker = mark();
|
PsiBuilder.Marker blockMarker = mark();
|
||||||
|
|
||||||
myExpressionParsing.parseStatements();
|
myExpressionParsing.parseStatements(/*isScriptTopLevel = */true);
|
||||||
|
|
||||||
checkForUnexpectedSymbols();
|
checkForUnexpectedSymbols();
|
||||||
|
|
||||||
|
|||||||
@@ -18,6 +18,7 @@ package org.jetbrains.kotlin.psi;
|
|||||||
|
|
||||||
import com.intellij.lang.ASTNode;
|
import com.intellij.lang.ASTNode;
|
||||||
import com.intellij.psi.PsiElement;
|
import com.intellij.psi.PsiElement;
|
||||||
|
import com.intellij.psi.util.PsiTreeUtil;
|
||||||
import org.jetbrains.annotations.NotNull;
|
import org.jetbrains.annotations.NotNull;
|
||||||
import org.jetbrains.annotations.Nullable;
|
import org.jetbrains.annotations.Nullable;
|
||||||
import org.jetbrains.kotlin.lexer.KtTokens;
|
import org.jetbrains.kotlin.lexer.KtTokens;
|
||||||
@@ -59,4 +60,15 @@ public class KtClassInitializer extends KtDeclarationStub<KotlinPlaceHolderStub<
|
|||||||
public PsiElement getInitKeyword() {
|
public PsiElement getInitKeyword() {
|
||||||
return findChildByType(KtTokens.INIT_KEYWORD);
|
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')
|
PsiWhiteSpace('\n')
|
||||||
PsiElement(RBRACE)('}')
|
PsiElement(RBRACE)('}')
|
||||||
PsiWhiteSpace('\n\n')
|
PsiWhiteSpace('\n\n')
|
||||||
IF
|
ANONYMOUS_INITIALIZER
|
||||||
PsiElement(if)('if')
|
IF
|
||||||
PsiWhiteSpace(' ')
|
PsiElement(if)('if')
|
||||||
PsiElement(LPAR)('(')
|
PsiWhiteSpace(' ')
|
||||||
CONDITION
|
PsiElement(LPAR)('(')
|
||||||
BINARY_EXPRESSION
|
CONDITION
|
||||||
DOT_QUALIFIED_EXPRESSION
|
BINARY_EXPRESSION
|
||||||
REFERENCE_EXPRESSION
|
DOT_QUALIFIED_EXPRESSION
|
||||||
PsiElement(IDENTIFIER)('args')
|
REFERENCE_EXPRESSION
|
||||||
PsiElement(DOT)('.')
|
PsiElement(IDENTIFIER)('args')
|
||||||
REFERENCE_EXPRESSION
|
PsiElement(DOT)('.')
|
||||||
PsiElement(IDENTIFIER)('length')
|
REFERENCE_EXPRESSION
|
||||||
PsiWhiteSpace(' ')
|
PsiElement(IDENTIFIER)('length')
|
||||||
OPERATION_REFERENCE
|
PsiWhiteSpace(' ')
|
||||||
PsiElement(EQEQ)('==')
|
OPERATION_REFERENCE
|
||||||
PsiWhiteSpace(' ')
|
PsiElement(EQEQ)('==')
|
||||||
INTEGER_CONSTANT
|
PsiWhiteSpace(' ')
|
||||||
PsiElement(INTEGER_LITERAL)('0')
|
INTEGER_CONSTANT
|
||||||
PsiElement(RPAR)(')')
|
PsiElement(INTEGER_LITERAL)('0')
|
||||||
PsiWhiteSpace(' ')
|
PsiElement(RPAR)(')')
|
||||||
THEN
|
PsiWhiteSpace(' ')
|
||||||
BLOCK
|
THEN
|
||||||
PsiElement(LBRACE)('{')
|
BLOCK
|
||||||
PsiWhiteSpace('\n ')
|
PsiElement(LBRACE)('{')
|
||||||
CALL_EXPRESSION
|
PsiWhiteSpace('\n ')
|
||||||
REFERENCE_EXPRESSION
|
CALL_EXPRESSION
|
||||||
PsiElement(IDENTIFIER)('die')
|
REFERENCE_EXPRESSION
|
||||||
VALUE_ARGUMENT_LIST
|
PsiElement(IDENTIFIER)('die')
|
||||||
PsiElement(LPAR)('(')
|
VALUE_ARGUMENT_LIST
|
||||||
VALUE_ARGUMENT
|
PsiElement(LPAR)('(')
|
||||||
STRING_TEMPLATE
|
VALUE_ARGUMENT
|
||||||
PsiElement(OPEN_QUOTE)('"')
|
STRING_TEMPLATE
|
||||||
LITERAL_STRING_TEMPLATE_ENTRY
|
PsiElement(OPEN_QUOTE)('"')
|
||||||
PsiElement(REGULAR_STRING_PART)('Need arguments')
|
LITERAL_STRING_TEMPLATE_ENTRY
|
||||||
PsiElement(CLOSING_QUOTE)('"')
|
PsiElement(REGULAR_STRING_PART)('Need arguments')
|
||||||
PsiElement(RPAR)(')')
|
PsiElement(CLOSING_QUOTE)('"')
|
||||||
PsiWhiteSpace('\n')
|
PsiElement(RPAR)(')')
|
||||||
PsiElement(RBRACE)('}')
|
PsiWhiteSpace('\n')
|
||||||
|
PsiElement(RBRACE)('}')
|
||||||
PsiWhiteSpace('\n\n')
|
PsiWhiteSpace('\n\n')
|
||||||
FOR
|
ANONYMOUS_INITIALIZER
|
||||||
PsiElement(for)('for')
|
FOR
|
||||||
PsiWhiteSpace(' ')
|
PsiElement(for)('for')
|
||||||
PsiElement(LPAR)('(')
|
PsiWhiteSpace(' ')
|
||||||
VALUE_PARAMETER
|
PsiElement(LPAR)('(')
|
||||||
PsiElement(IDENTIFIER)('arg')
|
VALUE_PARAMETER
|
||||||
PsiWhiteSpace(' ')
|
PsiElement(IDENTIFIER)('arg')
|
||||||
PsiElement(in)('in')
|
PsiWhiteSpace(' ')
|
||||||
PsiWhiteSpace(' ')
|
PsiElement(in)('in')
|
||||||
LOOP_RANGE
|
PsiWhiteSpace(' ')
|
||||||
REFERENCE_EXPRESSION
|
LOOP_RANGE
|
||||||
PsiElement(IDENTIFIER)('args')
|
REFERENCE_EXPRESSION
|
||||||
PsiElement(RPAR)(')')
|
PsiElement(IDENTIFIER)('args')
|
||||||
PsiWhiteSpace(' ')
|
PsiElement(RPAR)(')')
|
||||||
BODY
|
PsiWhiteSpace(' ')
|
||||||
BLOCK
|
BODY
|
||||||
PsiElement(LBRACE)('{')
|
BLOCK
|
||||||
PsiWhiteSpace('\n ')
|
PsiElement(LBRACE)('{')
|
||||||
CALL_EXPRESSION
|
PsiWhiteSpace('\n ')
|
||||||
REFERENCE_EXPRESSION
|
CALL_EXPRESSION
|
||||||
PsiElement(IDENTIFIER)('println')
|
REFERENCE_EXPRESSION
|
||||||
VALUE_ARGUMENT_LIST
|
PsiElement(IDENTIFIER)('println')
|
||||||
PsiElement(LPAR)('(')
|
VALUE_ARGUMENT_LIST
|
||||||
VALUE_ARGUMENT
|
PsiElement(LPAR)('(')
|
||||||
REFERENCE_EXPRESSION
|
VALUE_ARGUMENT
|
||||||
PsiElement(IDENTIFIER)('arg')
|
REFERENCE_EXPRESSION
|
||||||
PsiElement(RPAR)(')')
|
PsiElement(IDENTIFIER)('arg')
|
||||||
PsiWhiteSpace('\n')
|
PsiElement(RPAR)(')')
|
||||||
PsiElement(RBRACE)('}')
|
PsiWhiteSpace('\n')
|
||||||
|
PsiElement(RBRACE)('}')
|
||||||
+10
-9
@@ -7,12 +7,13 @@ JetFile: Shebang.kts
|
|||||||
PsiWhiteSpace('\n\n')
|
PsiWhiteSpace('\n\n')
|
||||||
SCRIPT
|
SCRIPT
|
||||||
BLOCK
|
BLOCK
|
||||||
CALL_EXPRESSION
|
ANONYMOUS_INITIALIZER
|
||||||
REFERENCE_EXPRESSION
|
CALL_EXPRESSION
|
||||||
PsiElement(IDENTIFIER)('println')
|
REFERENCE_EXPRESSION
|
||||||
VALUE_ARGUMENT_LIST
|
PsiElement(IDENTIFIER)('println')
|
||||||
PsiElement(LPAR)('(')
|
VALUE_ARGUMENT_LIST
|
||||||
VALUE_ARGUMENT
|
PsiElement(LPAR)('(')
|
||||||
REFERENCE_EXPRESSION
|
VALUE_ARGUMENT
|
||||||
PsiElement(IDENTIFIER)('args')
|
REFERENCE_EXPRESSION
|
||||||
PsiElement(RPAR)(')')
|
PsiElement(IDENTIFIER)('args')
|
||||||
|
PsiElement(RPAR)(')')
|
||||||
+20
-18
@@ -5,30 +5,32 @@ JetFile: ShebangIncorrect.kts
|
|||||||
<empty list>
|
<empty list>
|
||||||
SCRIPT
|
SCRIPT
|
||||||
BLOCK
|
BLOCK
|
||||||
CALL_EXPRESSION
|
ANONYMOUS_INITIALIZER
|
||||||
REFERENCE_EXPRESSION
|
CALL_EXPRESSION
|
||||||
PsiElement(IDENTIFIER)('println')
|
REFERENCE_EXPRESSION
|
||||||
VALUE_ARGUMENT_LIST
|
PsiElement(IDENTIFIER)('println')
|
||||||
PsiElement(LPAR)('(')
|
VALUE_ARGUMENT_LIST
|
||||||
VALUE_ARGUMENT
|
PsiElement(LPAR)('(')
|
||||||
INTEGER_CONSTANT
|
VALUE_ARGUMENT
|
||||||
PsiElement(INTEGER_LITERAL)('1')
|
INTEGER_CONSTANT
|
||||||
PsiElement(RPAR)(')')
|
PsiElement(INTEGER_LITERAL)('1')
|
||||||
|
PsiElement(RPAR)(')')
|
||||||
PsiElement(SEMICOLON)(';')
|
PsiElement(SEMICOLON)(';')
|
||||||
PsiWhiteSpace(' ')
|
PsiWhiteSpace(' ')
|
||||||
PsiErrorElement:Expecting an element
|
PsiErrorElement:Expecting an element
|
||||||
PsiElement(HASH)('#')
|
PsiElement(HASH)('#')
|
||||||
BINARY_EXPRESSION
|
ANONYMOUS_INITIALIZER
|
||||||
PREFIX_EXPRESSION
|
BINARY_EXPRESSION
|
||||||
|
PREFIX_EXPRESSION
|
||||||
|
OPERATION_REFERENCE
|
||||||
|
PsiElement(EXCL)('!')
|
||||||
|
PsiErrorElement:Expecting an element
|
||||||
|
PsiElement(DIV)('/')
|
||||||
OPERATION_REFERENCE
|
OPERATION_REFERENCE
|
||||||
PsiElement(EXCL)('!')
|
PsiElement(IDENTIFIER)('usr')
|
||||||
|
PsiWhiteSpace('\n\n')
|
||||||
PsiErrorElement:Expecting an element
|
PsiErrorElement:Expecting an element
|
||||||
PsiElement(DIV)('/')
|
PsiElement(HASH)('#')
|
||||||
OPERATION_REFERENCE
|
|
||||||
PsiElement(IDENTIFIER)('usr')
|
|
||||||
PsiWhiteSpace('\n\n')
|
|
||||||
PsiErrorElement:Expecting an element
|
|
||||||
PsiElement(HASH)('#')
|
|
||||||
PsiErrorElement:Unexpected tokens (use ';' to separate expressions on the same line)
|
PsiErrorElement:Unexpected tokens (use ';' to separate expressions on the same line)
|
||||||
PsiElement(EXCL)('!')
|
PsiElement(EXCL)('!')
|
||||||
PsiElement(DIV)('/')
|
PsiElement(DIV)('/')
|
||||||
|
|||||||
+10
-9
@@ -5,12 +5,13 @@ JetFile: SimpleScript.kts
|
|||||||
<empty list>
|
<empty list>
|
||||||
SCRIPT
|
SCRIPT
|
||||||
BLOCK
|
BLOCK
|
||||||
CALL_EXPRESSION
|
ANONYMOUS_INITIALIZER
|
||||||
REFERENCE_EXPRESSION
|
CALL_EXPRESSION
|
||||||
PsiElement(IDENTIFIER)('println')
|
REFERENCE_EXPRESSION
|
||||||
VALUE_ARGUMENT_LIST
|
PsiElement(IDENTIFIER)('println')
|
||||||
PsiElement(LPAR)('(')
|
VALUE_ARGUMENT_LIST
|
||||||
VALUE_ARGUMENT
|
PsiElement(LPAR)('(')
|
||||||
INTEGER_CONSTANT
|
VALUE_ARGUMENT
|
||||||
PsiElement(INTEGER_LITERAL)('1')
|
INTEGER_CONSTANT
|
||||||
PsiElement(RPAR)(')')
|
PsiElement(INTEGER_LITERAL)('1')
|
||||||
|
PsiElement(RPAR)(')')
|
||||||
+10
-9
@@ -5,15 +5,16 @@ JetFile: unexpectedSymbol.kts
|
|||||||
<empty list>
|
<empty list>
|
||||||
SCRIPT
|
SCRIPT
|
||||||
BLOCK
|
BLOCK
|
||||||
CALL_EXPRESSION
|
ANONYMOUS_INITIALIZER
|
||||||
REFERENCE_EXPRESSION
|
CALL_EXPRESSION
|
||||||
PsiElement(IDENTIFIER)('println')
|
REFERENCE_EXPRESSION
|
||||||
VALUE_ARGUMENT_LIST
|
PsiElement(IDENTIFIER)('println')
|
||||||
PsiElement(LPAR)('(')
|
VALUE_ARGUMENT_LIST
|
||||||
VALUE_ARGUMENT
|
PsiElement(LPAR)('(')
|
||||||
INTEGER_CONSTANT
|
VALUE_ARGUMENT
|
||||||
PsiElement(INTEGER_LITERAL)('1')
|
INTEGER_CONSTANT
|
||||||
PsiElement(RPAR)(')')
|
PsiElement(INTEGER_LITERAL)('1')
|
||||||
|
PsiElement(RPAR)(')')
|
||||||
PsiWhiteSpace('\n')
|
PsiWhiteSpace('\n')
|
||||||
PsiErrorElement:unexpected symbol
|
PsiErrorElement:unexpected symbol
|
||||||
PsiElement(RBRACE)('}')
|
PsiElement(RBRACE)('}')
|
||||||
@@ -41,6 +41,12 @@ public abstract class AbstractParsingTest extends ParsingTestCase {
|
|||||||
System.setProperty("idea.platform.prefix", "Idea");
|
System.setProperty("idea.platform.prefix", "Idea");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected void setUp() throws Exception {
|
||||||
|
super.setUp();
|
||||||
|
getProject().registerService(KotlinScriptDefinitionProvider.class);
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
protected String getTestDataPath() {
|
protected String getTestDataPath() {
|
||||||
return KotlinTestUtils.getHomeDirectory();
|
return KotlinTestUtils.getHomeDirectory();
|
||||||
|
|||||||
Reference in New Issue
Block a user