JET-174 Make continue work the same way in all contexts inside when
Guards are removed. Continue is not supported yet.
This commit is contained in:
@@ -12,12 +12,8 @@ when
|
||||
|
||||
whenEntry
|
||||
// TODO : consider empty after =>
|
||||
: whenConditionIf{","} (when | "=>" expression SEMI)
|
||||
: "else" ("continue" | "=>" expression SEMI)
|
||||
;
|
||||
|
||||
whenConditionIf
|
||||
: whenCondition ("if" "(" expression ")")?
|
||||
: whenCondition{","} "=>" expression SEMI
|
||||
: "else" "=>" expression SEMI
|
||||
;
|
||||
|
||||
whenCondition
|
||||
|
||||
@@ -630,9 +630,6 @@ public class JetControlFlowProcessor {
|
||||
Label nextLabel = builder.createUnboundLabel();
|
||||
for (Iterator<JetWhenEntry> iterator = expression.getEntries().iterator(); iterator.hasNext(); ) {
|
||||
JetWhenEntry whenEntry = iterator.next();
|
||||
if (whenEntry.getSubWhen() != null) throw new UnsupportedOperationException(); // TODO
|
||||
|
||||
if (whenEntry.isElseContinue()) throw new UnsupportedOperationException(); // TODO
|
||||
|
||||
if (whenEntry.isElse()) {
|
||||
if (iterator.hasNext()) {
|
||||
|
||||
@@ -635,8 +635,8 @@ public class JetExpressionParsing extends AbstractJetParsing {
|
||||
/*
|
||||
* whenEntry
|
||||
* // TODO : consider empty after =>
|
||||
* : whenConditionIf{","} (when | "=>" element SEMI)
|
||||
* : "else" ("continue" | "=>" element SEMI)
|
||||
* : whenCondition{","} "=>" element SEMI
|
||||
* : "else" "=>" element SEMI
|
||||
* ;
|
||||
*/
|
||||
private void parseWhenEntry() {
|
||||
@@ -645,8 +645,8 @@ public class JetExpressionParsing extends AbstractJetParsing {
|
||||
if (at(ELSE_KEYWORD)) {
|
||||
advance(); // ELSE_KEYWORD
|
||||
|
||||
if (!at(CONTINUE_KEYWORD) && !at(DOUBLE_ARROW)) {
|
||||
errorUntil("Expecting 'continue' or '=> element'", TokenSet.create(CONTINUE_KEYWORD, DOUBLE_ARROW,
|
||||
if (!at(DOUBLE_ARROW)) {
|
||||
errorUntil("Expecting '=>'", TokenSet.create(DOUBLE_ARROW,
|
||||
RBRACE, EOL_OR_SEMICOLON));
|
||||
}
|
||||
|
||||
@@ -658,10 +658,8 @@ public class JetExpressionParsing extends AbstractJetParsing {
|
||||
} else {
|
||||
parseExpression();
|
||||
}
|
||||
} else if (at(CONTINUE_KEYWORD)) {
|
||||
advance(); // CONTINUE_KEYWORD
|
||||
} else if (!atSet(WHEN_CONDITION_RECOVERY_SET)) {
|
||||
errorAndAdvance("Expecting 'continue' or '=> element'");
|
||||
errorAndAdvance("Expecting '=>'");
|
||||
}
|
||||
} else {
|
||||
parseWhenEntryNotElse();
|
||||
@@ -672,48 +670,22 @@ public class JetExpressionParsing extends AbstractJetParsing {
|
||||
}
|
||||
|
||||
/*
|
||||
* : whenConditionIf{","} (when | "=>" element SEMI)
|
||||
* : whenCondition{","} "=>" element SEMI
|
||||
*/
|
||||
private void parseWhenEntryNotElse() {
|
||||
while (true) {
|
||||
while (at(COMMA)) errorAndAdvance("Expecting a when-condition");
|
||||
parseWhenConditionIf();
|
||||
parseWhenCondition();
|
||||
if (!at(COMMA)) break;
|
||||
advance(); // COMMA
|
||||
}
|
||||
if (at(WHEN_KEYWORD)) {
|
||||
parseWhen();
|
||||
expect(DOUBLE_ARROW, "Expecting '=>' or 'when'", WHEN_CONDITION_RECOVERY_SET);
|
||||
if (atSet(WHEN_CONDITION_RECOVERY_SET)) {
|
||||
error("Expecting an element");
|
||||
} else {
|
||||
expect(DOUBLE_ARROW, "Expecting '=>' or 'when'", WHEN_CONDITION_RECOVERY_SET);
|
||||
if (atSet(WHEN_CONDITION_RECOVERY_SET)) {
|
||||
error("Expecting an element");
|
||||
} else {
|
||||
parseExpression();
|
||||
}
|
||||
// SEMI is consumed in parseWhenEntry
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* whenConditionIf
|
||||
* : pattern ("if" "(" element ")")?
|
||||
* ;
|
||||
*/
|
||||
private void parseWhenConditionIf() {
|
||||
parseWhenCondition();
|
||||
|
||||
if (at(IF_KEYWORD)) {
|
||||
advance(); // IF_KEYWORD
|
||||
|
||||
// TODO : allow omitting these parentheses
|
||||
myBuilder.disableNewlines();
|
||||
expect(LPAR, "Expecting '('");
|
||||
|
||||
parseExpression();
|
||||
|
||||
expect(RPAR, "Expecting ')'");
|
||||
myBuilder.restoreNewlinesState();
|
||||
}
|
||||
// SEMI is consumed in parseWhenEntry
|
||||
}
|
||||
|
||||
/*
|
||||
|
||||
@@ -3,7 +3,6 @@ package org.jetbrains.jet.lang.psi;
|
||||
import com.intellij.lang.ASTNode;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
import org.jetbrains.jet.JetNodeTypes;
|
||||
import org.jetbrains.jet.lexer.JetTokens;
|
||||
|
||||
/**
|
||||
@@ -18,21 +17,11 @@ public class JetWhenEntry extends JetElement {
|
||||
return findChildByType(JetTokens.ELSE_KEYWORD) != null;
|
||||
}
|
||||
|
||||
public boolean isElseContinue() {
|
||||
return isElse() && (findChildByType(JetTokens.DOUBLE_ARROW) == null) && (findChildByType(JetTokens.CONTINUE_KEYWORD) != null);
|
||||
}
|
||||
|
||||
@Nullable
|
||||
public JetExpression getExpression() {
|
||||
return findChildByClass(JetExpression.class);
|
||||
}
|
||||
|
||||
@Nullable
|
||||
public JetWhenExpression getSubWhen() {
|
||||
// TODO: this may be a WHEN that goes after "=>"
|
||||
return (JetWhenExpression) findChildByType(JetNodeTypes.WHEN);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void accept(@NotNull JetVisitor visitor) {
|
||||
visitor.visitWhenEntry(this);
|
||||
|
||||
@@ -1324,8 +1324,7 @@ public class JetTypeInferrer {
|
||||
newDataFlowInfo = newDataFlowInfo.and(context.dataFlowInfo);
|
||||
}
|
||||
}
|
||||
JetWhenExpression subWhen = whenEntry.getSubWhen();
|
||||
JetExpression bodyExpression = subWhen == null ? whenEntry.getExpression() : subWhen;
|
||||
JetExpression bodyExpression = whenEntry.getExpression();
|
||||
if (bodyExpression != null) {
|
||||
JetType type = getTypeWithNewDataFlowInfo(scopeToExtend, bodyExpression, true, newDataFlowInfo);
|
||||
if (type != null) {
|
||||
@@ -1436,8 +1435,11 @@ public class JetTypeInferrer {
|
||||
|
||||
@Override
|
||||
public void visitExpressionPattern(JetExpressionPattern pattern) {
|
||||
JetType type = getType(scopeToExtend, pattern.getExpression(), false);
|
||||
checkTypeCompatibility(type, subjectType, pattern);
|
||||
JetExpression expression = pattern.getExpression();
|
||||
if (expression != null) {
|
||||
JetType type = getType(scopeToExtend, expression, false);
|
||||
checkTypeCompatibility(type, subjectType, pattern);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
|
||||
@@ -10,14 +10,13 @@ fun foo() {
|
||||
|
||||
fun foo() {
|
||||
when (e) {
|
||||
|
||||
|
||||
}
|
||||
when (e) {
|
||||
is a => foo
|
||||
}
|
||||
when (e) {
|
||||
is Tree @ (a, b) => foo
|
||||
is Tree @ (a, b) if (a > 5) => foo
|
||||
is null => foo
|
||||
is 1 => foo
|
||||
is A.b => foo
|
||||
@@ -58,7 +57,6 @@ fun foo() {
|
||||
is (Int, Int) => 2
|
||||
is val a : Foo => 2
|
||||
else => foo
|
||||
else continue
|
||||
}
|
||||
}
|
||||
|
||||
@@ -72,4 +70,3 @@ fun foo() {
|
||||
is a.a @ (val b, b) if (b == a + 3) => c
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
+23
-68
@@ -94,7 +94,7 @@ JetFile: When.jet
|
||||
PsiElement(RPAR)(')')
|
||||
PsiWhiteSpace(' ')
|
||||
PsiElement(LBRACE)('{')
|
||||
PsiWhiteSpace('\n\n ')
|
||||
PsiWhiteSpace('\n \n ')
|
||||
PsiElement(RBRACE)('}')
|
||||
PsiWhiteSpace('\n ')
|
||||
WHEN
|
||||
@@ -167,53 +167,6 @@ JetFile: When.jet
|
||||
REFERENCE_EXPRESSION
|
||||
PsiElement(IDENTIFIER)('foo')
|
||||
PsiWhiteSpace('\n ')
|
||||
WHEN_ENTRY
|
||||
WHEN_CONDITION_IS_PATTERN
|
||||
PsiElement(is)('is')
|
||||
PsiWhiteSpace(' ')
|
||||
DECOMPOSER_PATTERN
|
||||
REFERENCE_EXPRESSION
|
||||
PsiElement(IDENTIFIER)('Tree')
|
||||
PsiWhiteSpace(' ')
|
||||
PsiElement(AT)('@')
|
||||
PsiWhiteSpace(' ')
|
||||
DECOMPOSER_ARGUMENT_LIST
|
||||
PsiElement(LPAR)('(')
|
||||
TUPLE_PATTERN_ENTRY
|
||||
TYPE_PATTERN
|
||||
TYPE_REFERENCE
|
||||
USER_TYPE
|
||||
REFERENCE_EXPRESSION
|
||||
PsiElement(IDENTIFIER)('a')
|
||||
PsiElement(COMMA)(',')
|
||||
PsiWhiteSpace(' ')
|
||||
TUPLE_PATTERN_ENTRY
|
||||
TYPE_PATTERN
|
||||
TYPE_REFERENCE
|
||||
USER_TYPE
|
||||
REFERENCE_EXPRESSION
|
||||
PsiElement(IDENTIFIER)('b')
|
||||
PsiElement(RPAR)(')')
|
||||
PsiWhiteSpace(' ')
|
||||
PsiElement(if)('if')
|
||||
PsiWhiteSpace(' ')
|
||||
PsiElement(LPAR)('(')
|
||||
BINARY_EXPRESSION
|
||||
REFERENCE_EXPRESSION
|
||||
PsiElement(IDENTIFIER)('a')
|
||||
PsiWhiteSpace(' ')
|
||||
OPERATION_REFERENCE
|
||||
PsiElement(GT)('>')
|
||||
PsiWhiteSpace(' ')
|
||||
INTEGER_CONSTANT
|
||||
PsiElement(INTEGER_LITERAL)('5')
|
||||
PsiElement(RPAR)(')')
|
||||
PsiWhiteSpace(' ')
|
||||
PsiElement(DOUBLE_ARROW)('=>')
|
||||
PsiWhiteSpace(' ')
|
||||
REFERENCE_EXPRESSION
|
||||
PsiElement(IDENTIFIER)('foo')
|
||||
PsiWhiteSpace('\n ')
|
||||
WHEN_ENTRY
|
||||
WHEN_CONDITION_IS_PATTERN
|
||||
PsiElement(is)('is')
|
||||
@@ -1039,11 +992,6 @@ JetFile: When.jet
|
||||
PsiWhiteSpace(' ')
|
||||
REFERENCE_EXPRESSION
|
||||
PsiElement(IDENTIFIER)('foo')
|
||||
PsiWhiteSpace('\n ')
|
||||
WHEN_ENTRY
|
||||
PsiElement(else)('else')
|
||||
PsiWhiteSpace(' ')
|
||||
PsiElement(continue)('continue')
|
||||
PsiWhiteSpace('\n ')
|
||||
PsiElement(RBRACE)('}')
|
||||
PsiWhiteSpace('\n')
|
||||
@@ -1245,27 +1193,34 @@ JetFile: When.jet
|
||||
PsiElement(IDENTIFIER)('b')
|
||||
PsiElement(RPAR)(')')
|
||||
PsiWhiteSpace(' ')
|
||||
PsiElement(if)('if')
|
||||
PsiErrorElement:Expecting '=>' or 'when'
|
||||
PsiElement(if)('if')
|
||||
PsiWhiteSpace(' ')
|
||||
PsiElement(LPAR)('(')
|
||||
BINARY_EXPRESSION
|
||||
REFERENCE_EXPRESSION
|
||||
PsiElement(IDENTIFIER)('b')
|
||||
PsiWhiteSpace(' ')
|
||||
OPERATION_REFERENCE
|
||||
PsiElement(EQEQ)('==')
|
||||
PsiWhiteSpace(' ')
|
||||
PARENTHESIZED
|
||||
PsiElement(LPAR)('(')
|
||||
BINARY_EXPRESSION
|
||||
REFERENCE_EXPRESSION
|
||||
PsiElement(IDENTIFIER)('a')
|
||||
PsiElement(IDENTIFIER)('b')
|
||||
PsiWhiteSpace(' ')
|
||||
OPERATION_REFERENCE
|
||||
PsiElement(PLUS)('+')
|
||||
PsiElement(EQEQ)('==')
|
||||
PsiWhiteSpace(' ')
|
||||
INTEGER_CONSTANT
|
||||
PsiElement(INTEGER_LITERAL)('3')
|
||||
PsiElement(RPAR)(')')
|
||||
PsiWhiteSpace(' ')
|
||||
BINARY_EXPRESSION
|
||||
REFERENCE_EXPRESSION
|
||||
PsiElement(IDENTIFIER)('a')
|
||||
PsiWhiteSpace(' ')
|
||||
OPERATION_REFERENCE
|
||||
PsiElement(PLUS)('+')
|
||||
PsiWhiteSpace(' ')
|
||||
INTEGER_CONSTANT
|
||||
PsiElement(INTEGER_LITERAL)('3')
|
||||
PsiElement(RPAR)(')')
|
||||
PsiWhiteSpace(' ')
|
||||
WHEN_ENTRY
|
||||
WHEN_CONDITION_IS_PATTERN
|
||||
EXPRESSION_PATTERN
|
||||
PsiErrorElement:Expecting an element, is-condition or in-condition
|
||||
<empty list>
|
||||
PsiElement(DOUBLE_ARROW)('=>')
|
||||
PsiWhiteSpace(' ')
|
||||
REFERENCE_EXPRESSION
|
||||
|
||||
@@ -91,7 +91,7 @@ JetFile: When_ERR.jet
|
||||
PsiWhiteSpace('\n ')
|
||||
WHEN_ENTRY
|
||||
PsiElement(else)('else')
|
||||
PsiErrorElement:Expecting 'continue' or '=> element'
|
||||
PsiErrorElement:Expecting '=>'
|
||||
<empty list>
|
||||
PsiWhiteSpace('\n ')
|
||||
PsiElement(RBRACE)('}')
|
||||
@@ -172,7 +172,7 @@ JetFile: When_ERR.jet
|
||||
PsiWhiteSpace('\n ')
|
||||
WHEN_ENTRY
|
||||
PsiElement(else)('else')
|
||||
PsiErrorElement:Expecting 'continue' or '=> element'
|
||||
PsiErrorElement:Expecting '=>'
|
||||
<empty list>
|
||||
PsiWhiteSpace('\n ')
|
||||
WHEN_ENTRY
|
||||
|
||||
@@ -121,8 +121,6 @@ public class JetTypeCheckerTest extends LightDaemonAnalyzerTestCase {
|
||||
assertType("when (1) { is 1 => 2; is 1 => '2'} ", "Any");
|
||||
assertType("when (1) { is 1 => 2; is 1 => '2'; is 1 => null} ", "Any?");
|
||||
assertType("when (1) { is 1 => 2; is 1 => '2'; else => null} ", "Any?");
|
||||
assertType("when (1) { is 1 => 2; is 1 => '2'; else continue} ", "Any");
|
||||
assertType("when (1) { is 1 => 2; is 1 => '2'; is 1 when(e) {is 1 => null}} ", "Any?");
|
||||
assertType("when (1) { is 1 => 2; is 1 => '2'; is 1 => when(e) {is 1 => null}} ", "Any?");
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user