Mark string prefixes and suffixes as unsupported
This commit is contained in:
+31
-2
@@ -31,6 +31,8 @@ import org.jetbrains.kotlin.builtins.KotlinBuiltIns;
|
|||||||
import org.jetbrains.kotlin.descriptors.*;
|
import org.jetbrains.kotlin.descriptors.*;
|
||||||
import org.jetbrains.kotlin.descriptors.annotations.Annotations;
|
import org.jetbrains.kotlin.descriptors.annotations.Annotations;
|
||||||
import org.jetbrains.kotlin.diagnostics.Diagnostic;
|
import org.jetbrains.kotlin.diagnostics.Diagnostic;
|
||||||
|
import org.jetbrains.kotlin.diagnostics.Errors;
|
||||||
|
import org.jetbrains.kotlin.lexer.JetKeywordToken;
|
||||||
import org.jetbrains.kotlin.lexer.JetTokens;
|
import org.jetbrains.kotlin.lexer.JetTokens;
|
||||||
import org.jetbrains.kotlin.name.Name;
|
import org.jetbrains.kotlin.name.Name;
|
||||||
import org.jetbrains.kotlin.psi.*;
|
import org.jetbrains.kotlin.psi.*;
|
||||||
@@ -73,8 +75,7 @@ import java.util.Iterator;
|
|||||||
import java.util.List;
|
import java.util.List;
|
||||||
|
|
||||||
import static org.jetbrains.kotlin.diagnostics.Errors.*;
|
import static org.jetbrains.kotlin.diagnostics.Errors.*;
|
||||||
import static org.jetbrains.kotlin.lexer.JetTokens.AS_KEYWORD;
|
import static org.jetbrains.kotlin.lexer.JetTokens.*;
|
||||||
import static org.jetbrains.kotlin.lexer.JetTokens.AS_SAFE;
|
|
||||||
import static org.jetbrains.kotlin.resolve.BindingContext.*;
|
import static org.jetbrains.kotlin.resolve.BindingContext.*;
|
||||||
import static org.jetbrains.kotlin.resolve.calls.context.ContextDependency.DEPENDENT;
|
import static org.jetbrains.kotlin.resolve.calls.context.ContextDependency.DEPENDENT;
|
||||||
import static org.jetbrains.kotlin.resolve.calls.context.ContextDependency.INDEPENDENT;
|
import static org.jetbrains.kotlin.resolve.calls.context.ContextDependency.INDEPENDENT;
|
||||||
@@ -115,6 +116,10 @@ public class BasicExpressionTypingVisitor extends ExpressionTypingVisitor {
|
|||||||
|
|
||||||
@Override
|
@Override
|
||||||
public JetTypeInfo visitConstantExpression(@NotNull JetConstantExpression expression, ExpressionTypingContext context) {
|
public JetTypeInfo visitConstantExpression(@NotNull JetConstantExpression expression, ExpressionTypingContext context) {
|
||||||
|
if (expression.getNode().getElementType() == JetNodeTypes.CHARACTER_CONSTANT) {
|
||||||
|
checkStringPrefixAndSuffix(expression, context);
|
||||||
|
}
|
||||||
|
|
||||||
CompileTimeConstant<?> compileTimeConstant = components.constantExpressionEvaluator.evaluateExpression(
|
CompileTimeConstant<?> compileTimeConstant = components.constantExpressionEvaluator.evaluateExpression(
|
||||||
expression, context.trace, context.expectedType
|
expression, context.trace, context.expectedType
|
||||||
);
|
);
|
||||||
@@ -1372,6 +1377,9 @@ public class BasicExpressionTypingVisitor extends ExpressionTypingVisitor {
|
|||||||
@Override
|
@Override
|
||||||
public JetTypeInfo visitStringTemplateExpression(@NotNull JetStringTemplateExpression expression, ExpressionTypingContext contextWithExpectedType) {
|
public JetTypeInfo visitStringTemplateExpression(@NotNull JetStringTemplateExpression expression, ExpressionTypingContext contextWithExpectedType) {
|
||||||
final ExpressionTypingContext context = contextWithExpectedType.replaceExpectedType(NO_EXPECTED_TYPE).replaceContextDependency(INDEPENDENT);
|
final ExpressionTypingContext context = contextWithExpectedType.replaceExpectedType(NO_EXPECTED_TYPE).replaceContextDependency(INDEPENDENT);
|
||||||
|
|
||||||
|
checkStringPrefixAndSuffix(expression, context);
|
||||||
|
|
||||||
class StringTemplateVisitor extends JetVisitorVoid {
|
class StringTemplateVisitor extends JetVisitorVoid {
|
||||||
private JetTypeInfo typeInfo = TypeInfoFactoryKt.noTypeInfo(context);
|
private JetTypeInfo typeInfo = TypeInfoFactoryKt.noTypeInfo(context);
|
||||||
|
|
||||||
@@ -1402,6 +1410,27 @@ public class BasicExpressionTypingVisitor extends ExpressionTypingVisitor {
|
|||||||
contextWithExpectedType);
|
contextWithExpectedType);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private static void checkStringPrefixAndSuffix(@NotNull PsiElement expression, ExpressionTypingContext context) {
|
||||||
|
checkStringPrefixOrSuffix(PsiTreeUtil.prevLeaf(expression), context);
|
||||||
|
checkStringPrefixOrSuffix(PsiTreeUtil.nextLeaf(expression), context);
|
||||||
|
}
|
||||||
|
|
||||||
|
private static void checkStringPrefixOrSuffix(PsiElement prefixOrSuffix, ExpressionTypingContext context) {
|
||||||
|
if (illegalStringPrefixOrSuffix(prefixOrSuffix)) {
|
||||||
|
context.trace.report(Errors.UNSUPPORTED.on(prefixOrSuffix, "string prefixes and suffixes"));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private static boolean illegalStringPrefixOrSuffix(@Nullable PsiElement element) {
|
||||||
|
if (element == null) return false;
|
||||||
|
|
||||||
|
IElementType elementType = element.getNode().getElementType();
|
||||||
|
return elementType == IDENTIFIER ||
|
||||||
|
elementType == INTEGER_LITERAL ||
|
||||||
|
elementType == FLOAT_LITERAL ||
|
||||||
|
elementType instanceof JetKeywordToken;
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public JetTypeInfo visitAnnotatedExpression(@NotNull JetAnnotatedExpression expression, ExpressionTypingContext context) {
|
public JetTypeInfo visitAnnotatedExpression(@NotNull JetAnnotatedExpression expression, ExpressionTypingContext context) {
|
||||||
return visitAnnotatedExpression(expression, context, false);
|
return visitAnnotatedExpression(expression, context, false);
|
||||||
|
|||||||
@@ -0,0 +1,39 @@
|
|||||||
|
// !DIAGNOSTICS: -UNUSED_PARAMETER
|
||||||
|
|
||||||
|
infix fun Any?.foo(a: Any) {}
|
||||||
|
operator fun Any?.contains(a: Any): Boolean = true
|
||||||
|
|
||||||
|
fun test(a: Any) {
|
||||||
|
|
||||||
|
a <!UNSUPPORTED!>foo<!>""
|
||||||
|
a <!UNSUPPORTED!>foo<!>"asd"
|
||||||
|
a <!UNSUPPORTED!>foo<!>"$a"
|
||||||
|
a <!UNSUPPORTED!>foo<!>"asd${a}sfsa"
|
||||||
|
a <!UNSUPPORTED!>foo<!>"""sdf"""
|
||||||
|
a <!UNSUPPORTED!>foo<!>'d'
|
||||||
|
a <!UNSUPPORTED!>foo<!><!EMPTY_CHARACTER_LITERAL!>''<!>
|
||||||
|
|
||||||
|
a <!UNSUPPORTED!>foo<!>""<!UNSUPPORTED!>foo<!> a
|
||||||
|
a <!UNSUPPORTED!>foo<!>"asd"<!UNSUPPORTED!>foo<!> a
|
||||||
|
a <!UNSUPPORTED!>foo<!>"$a"<!UNSUPPORTED!>foo<!> a
|
||||||
|
a <!UNSUPPORTED!>foo<!>"asd${a}sfsa"<!UNSUPPORTED!>foo<!> a
|
||||||
|
a <!UNSUPPORTED!>foo<!>"""sdf"""<!UNSUPPORTED!>foo<!> a
|
||||||
|
a <!UNSUPPORTED!>foo<!>'d'<!UNSUPPORTED!>foo<!> a
|
||||||
|
a <!UNSUPPORTED!>foo<!><!EMPTY_CHARACTER_LITERAL!>''<!><!UNSUPPORTED!>foo<!> a
|
||||||
|
|
||||||
|
a <!UNSUPPORTED!>in<!>"foo"
|
||||||
|
a <!UNSUPPORTED!>in<!>"""foo"""
|
||||||
|
a <!UNSUPPORTED!>in<!>'s'
|
||||||
|
a <!UNSUPPORTED!>in<!><!EMPTY_CHARACTER_LITERAL!>''<!>
|
||||||
|
|
||||||
|
a <!UNSUPPORTED!>!in<!>"foo"
|
||||||
|
a <!UNSUPPORTED!>!in<!>"""foo"""
|
||||||
|
a <!UNSUPPORTED!>!in<!>'s'
|
||||||
|
a <!UNSUPPORTED!>!in<!><!EMPTY_CHARACTER_LITERAL!>''<!>
|
||||||
|
|
||||||
|
if("s"<!UNSUPPORTED!>is<!> Any) {}
|
||||||
|
test("s"<!UNSUPPORTED!>as<!> Any)
|
||||||
|
|
||||||
|
a <!UNSUPPORTED!>foo<!>""<!UNSUPPORTED, SYNTAX!>1<!>
|
||||||
|
a <!UNSUPPORTED!>foo<!>""<!UNSUPPORTED, SYNTAX!>1.0<!>
|
||||||
|
}
|
||||||
@@ -0,0 +1,5 @@
|
|||||||
|
package
|
||||||
|
|
||||||
|
public fun test(/*0*/ a: kotlin.Any): kotlin.Unit
|
||||||
|
public operator fun kotlin.Any?.contains(/*0*/ a: kotlin.Any): kotlin.Boolean
|
||||||
|
public infix fun kotlin.Any?.foo(/*0*/ a: kotlin.Any): kotlin.Unit
|
||||||
@@ -589,6 +589,12 @@ public class JetDiagnosticsTestGenerated extends AbstractJetDiagnosticsTest {
|
|||||||
doTest(fileName);
|
doTest(fileName);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@TestMetadata("StringPrefixAndSuffix.kt")
|
||||||
|
public void testStringPrefixAndSuffix() throws Exception {
|
||||||
|
String fileName = JetTestUtils.navigationMetadata("compiler/testData/diagnostics/tests/StringPrefixAndSuffix.kt");
|
||||||
|
doTest(fileName);
|
||||||
|
}
|
||||||
|
|
||||||
@TestMetadata("StringTemplates.kt")
|
@TestMetadata("StringTemplates.kt")
|
||||||
public void testStringTemplates() throws Exception {
|
public void testStringTemplates() throws Exception {
|
||||||
String fileName = JetTestUtils.navigationMetadata("compiler/testData/diagnostics/tests/StringTemplates.kt");
|
String fileName = JetTestUtils.navigationMetadata("compiler/testData/diagnostics/tests/StringTemplates.kt");
|
||||||
|
|||||||
Reference in New Issue
Block a user