'sealed' reserved in front of when

This commit is contained in:
Andrey Breslav
2015-12-17 20:30:12 +03:00
parent c36eeadab1
commit 75ab0dd509
7 changed files with 81 additions and 1 deletions
@@ -27,6 +27,7 @@ import org.jetbrains.kotlin.descriptors.Modality;
import org.jetbrains.kotlin.diagnostics.Errors;
import org.jetbrains.kotlin.lexer.KtTokens;
import org.jetbrains.kotlin.psi.*;
import org.jetbrains.kotlin.psi.psiUtil.KtPsiUtilKt;
import org.jetbrains.kotlin.resolve.BindingContext;
import org.jetbrains.kotlin.resolve.BindingTrace;
import org.jetbrains.kotlin.resolve.CompileTimeConstantUtils;
@@ -283,4 +284,7 @@ public final class WhenChecker {
}
}
public static void checkReservedPrefix(@NotNull BindingTrace trace, @NotNull KtWhenExpression expression) {
KtPsiUtilKt.checkReservedPrefixWord(trace, expression.getWhenKeyword(), "sealed", "sealed when");
}
}
@@ -599,6 +599,25 @@ public class KtPsiUtil {
return PsiTreeUtil.skipSiblingsForward(element, PsiWhiteSpace.class, PsiComment.class);
}
@Nullable
public static PsiElement prevLeafIgnoringWhitespaceAndComments(@NotNull PsiElement element) {
PsiElement prev = PsiTreeUtil.prevLeaf(element, true);
while (prev != null && KtTokens.WHITE_SPACE_OR_COMMENT_BIT_SET.contains(prev.getNode().getElementType())) {
prev = PsiTreeUtil.prevLeaf(prev, true);
}
return prev;
}
@Nullable
public static PsiElement getPreviousWord(@NotNull PsiElement element, @NotNull String word) {
PsiElement prev = prevLeafIgnoringWhitespaceAndComments(element);
if (prev != null && prev.getNode().getElementType() == KtTokens.IDENTIFIER && word.equals(prev.getText())) {
return prev;
}
return null;
}
public static final Predicate<KtElement> ANY_JET_ELEMENT = new Predicate<KtElement>() {
@Override
public boolean apply(@Nullable KtElement input) {
@@ -25,6 +25,8 @@ import com.intellij.psi.PsiWhiteSpace
import com.intellij.psi.stubs.StubElement
import com.intellij.psi.util.PsiTreeUtil
import org.jetbrains.kotlin.KtNodeTypes
import org.jetbrains.kotlin.diagnostics.DiagnosticSink
import org.jetbrains.kotlin.diagnostics.Errors
import org.jetbrains.kotlin.lexer.KtModifierKeywordToken
import org.jetbrains.kotlin.lexer.KtTokens
import org.jetbrains.kotlin.name.Name
@@ -36,7 +38,6 @@ import org.jetbrains.kotlin.resolve.calls.model.ArgumentMatch
import org.jetbrains.kotlin.types.expressions.OperatorConventions
import java.util.*
import kotlin.test.assertTrue
import kotlin.text.Regex
// NOTE: in this file we collect only Kotlin-specific methods working with PSI and not modifying it
@@ -431,4 +432,10 @@ private val BAD_NEIGHBOUR_FOR_SIMPLE_TEMPLATE_ENTRY_PATTERN = Regex("[a-zA-Z0-9_
fun canPlaceAfterSimpleNameEntry(element: PsiElement?): Boolean {
val entryText = element?.text ?: return true
return !BAD_NEIGHBOUR_FOR_SIMPLE_TEMPLATE_ENTRY_PATTERN.matches(entryText)
}
fun checkReservedPrefixWord(sink: DiagnosticSink, element: PsiElement, word: String, message: String) {
KtPsiUtil.getPreviousWord(element, word)?.let {
sink.report(Errors.UNSUPPORTED.on(it, message))
}
}
@@ -75,6 +75,7 @@ public class PatternMatchingTypingVisitor extends ExpressionTypingVisitor {
public KotlinTypeInfo visitWhenExpression(KtWhenExpression expression, ExpressionTypingContext contextWithExpectedType, boolean isStatement) {
WhenChecker.checkDeprecatedWhenSyntax(contextWithExpectedType.trace, expression);
WhenChecker.checkReservedPrefix(contextWithExpectedType.trace, expression);
components.dataFlowAnalyzer.recordExpectedType(contextWithExpectedType.trace, expression, contextWithExpectedType.expectedType);
@@ -0,0 +1,37 @@
// !DIAGNOSTICS: -UNUSED_PARAMETER
infix fun Any.sealed(a: Any?) {}
val x = 1 <!UNSUPPORTED!>sealed<!> when (1) {
1 -> 1
else -> 2
}
val x1 = 1 <!UNSUPPORTED!>sealed<!> /**/ when (1) {
1 -> 1
else -> 2
}
fun foo() {
<!UNRESOLVED_REFERENCE, UNSUPPORTED!>sealed<!><!SYNTAX!><!> when {
else -> {}
}
1 <!UNSUPPORTED!>sealed<!> when {
else -> {}
}
1 sealed (when {
else -> {}
})
<!UNUSED_EXPRESSION!>1<!>
<!UNRESOLVED_REFERENCE, UNSUPPORTED!>sealed<!><!SYNTAX!><!> when {
else -> {}
}
1 <!UNSUPPORTED!>sealed<!>
when {
else -> {}
}
}
@@ -0,0 +1,6 @@
package
public val x: kotlin.Unit
public val x1: kotlin.Unit
public fun foo(): kotlin.Unit
public infix fun kotlin.Any.sealed(/*0*/ a: kotlin.Any?): kotlin.Unit
@@ -18186,6 +18186,12 @@ public class DiagnosticsTestGenerated extends AbstractDiagnosticsTest {
doTest(fileName);
}
@TestMetadata("ReservedExhaustiveWhen.kt")
public void testReservedExhaustiveWhen() throws Exception {
String fileName = KotlinTestUtils.navigationMetadata("compiler/testData/diagnostics/tests/when/ReservedExhaustiveWhen.kt");
doTest(fileName);
}
@TestMetadata("When.kt")
public void testWhen() throws Exception {
String fileName = KotlinTestUtils.navigationMetadata("compiler/testData/diagnostics/tests/when/When.kt");