Forbid prefixes and suffixes for numeric literals
This commit is contained in:
+13
-11
@@ -178,8 +178,11 @@ public class BasicExpressionTypingVisitor extends ExpressionTypingVisitor {
|
||||
|
||||
@Override
|
||||
public KotlinTypeInfo visitConstantExpression(@NotNull KtConstantExpression expression, ExpressionTypingContext context) {
|
||||
if (expression.getNode().getElementType() == KtNodeTypes.CHARACTER_CONSTANT) {
|
||||
checkStringPrefixAndSuffix(expression, context);
|
||||
IElementType elementType = expression.getNode().getElementType();
|
||||
if (elementType == KtNodeTypes.CHARACTER_CONSTANT
|
||||
|| elementType == KtNodeTypes.INTEGER_CONSTANT
|
||||
|| elementType == KtNodeTypes.FLOAT_CONSTANT) {
|
||||
checkLiteralPrefixAndSuffix(expression, context);
|
||||
}
|
||||
|
||||
CompileTimeConstant<?> compileTimeConstant = components.constantExpressionEvaluator.evaluateExpression(
|
||||
@@ -192,7 +195,6 @@ public class BasicExpressionTypingVisitor extends ExpressionTypingVisitor {
|
||||
compileTimeConstant != null ? ((TypedCompileTimeConstant) compileTimeConstant).getConstantValue() : null;
|
||||
boolean hasError = constantChecker.checkConstantExpressionType(constantValue, expression, context.expectedType);
|
||||
if (hasError) {
|
||||
IElementType elementType = expression.getNode().getElementType();
|
||||
return TypeInfoFactoryKt.createTypeInfo(getDefaultType(elementType), context);
|
||||
}
|
||||
}
|
||||
@@ -1482,7 +1484,7 @@ public class BasicExpressionTypingVisitor extends ExpressionTypingVisitor {
|
||||
final ExpressionTypingContext context = contextWithExpectedType.replaceExpectedType(NO_EXPECTED_TYPE)
|
||||
.replaceContextDependency(INDEPENDENT);
|
||||
|
||||
checkStringPrefixAndSuffix(expression, context);
|
||||
checkLiteralPrefixAndSuffix(expression, context);
|
||||
|
||||
class StringTemplateVisitor extends KtVisitorVoid {
|
||||
private KotlinTypeInfo typeInfo = TypeInfoFactoryKt.noTypeInfo(context);
|
||||
@@ -1515,18 +1517,18 @@ public class BasicExpressionTypingVisitor extends ExpressionTypingVisitor {
|
||||
contextWithExpectedType);
|
||||
}
|
||||
|
||||
private static void checkStringPrefixAndSuffix(@NotNull PsiElement expression, ExpressionTypingContext context) {
|
||||
checkStringPrefixOrSuffix(PsiTreeUtil.prevLeaf(expression), context);
|
||||
checkStringPrefixOrSuffix(PsiTreeUtil.nextLeaf(expression), context);
|
||||
private static void checkLiteralPrefixAndSuffix(@NotNull PsiElement expression, ExpressionTypingContext context) {
|
||||
checkLiteralPrefixOrSuffix(PsiTreeUtil.prevLeaf(expression), context);
|
||||
checkLiteralPrefixOrSuffix(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 void checkLiteralPrefixOrSuffix(PsiElement prefixOrSuffix, ExpressionTypingContext context) {
|
||||
if (illegalLiteralPrefixOrSuffix(prefixOrSuffix)) {
|
||||
context.trace.report(Errors.UNSUPPORTED.on(prefixOrSuffix, "literal prefixes and suffixes"));
|
||||
}
|
||||
}
|
||||
|
||||
private static boolean illegalStringPrefixOrSuffix(@Nullable PsiElement element) {
|
||||
private static boolean illegalLiteralPrefixOrSuffix(@Nullable PsiElement element) {
|
||||
if (element == null) return false;
|
||||
|
||||
IElementType elementType = element.getNode().getElementType();
|
||||
|
||||
@@ -0,0 +1,54 @@
|
||||
// !DIAGNOSTICS: -UNUSED_PARAMETER -USELESS_CAST
|
||||
|
||||
infix fun Any?.foo(a: Any) {}
|
||||
infix fun Any?.zoo(a: Any) {}
|
||||
infix fun Any?.Loo(a: Any) {}
|
||||
infix fun Any?.doo(a: Any) {}
|
||||
infix fun Any?.ddoo(a: Any) {}
|
||||
operator fun Any?.contains(a: Any): Boolean = true
|
||||
|
||||
fun test(a: Any) {
|
||||
1f<!UNSUPPORTED, UNRESOLVED_REFERENCE!>oo<!> a
|
||||
1f<!UNSUPPORTED!>foo<!> a
|
||||
1<!UNSUPPORTED!>doo<!> a
|
||||
1<!UNSUPPORTED!>ddoo<!> a
|
||||
1<!UNSUPPORTED, INFIX_MODIFIER_REQUIRED!>contains<!> a
|
||||
|
||||
1L<!UNSUPPORTED!>foo<!> a
|
||||
1L<!UNSUPPORTED, UNRESOLVED_REFERENCE!>oo<!> a
|
||||
1L<!UNSUPPORTED!>Loo<!> a
|
||||
|
||||
0b1<!UNSUPPORTED!>foo<!> a
|
||||
0b1L<!UNSUPPORTED!>foo<!> a
|
||||
0b1L<!UNSUPPORTED, UNRESOLVED_REFERENCE!>oo<!> a
|
||||
0b1L<!UNSUPPORTED!>Loo<!> a
|
||||
|
||||
0xf<!UNSUPPORTED, UNRESOLVED_REFERENCE!>oo<!> a
|
||||
0xff<!UNSUPPORTED, UNRESOLVED_REFERENCE!>oo<!> a
|
||||
0xfL<!UNSUPPORTED!>Loo<!> a
|
||||
|
||||
1.0f<!UNSUPPORTED, UNRESOLVED_REFERENCE!>oo<!> a
|
||||
1.0f<!UNSUPPORTED!>foo<!> a
|
||||
1.0<!UNSUPPORTED!>doo<!> a
|
||||
1.0<!UNSUPPORTED!>ddoo<!> a
|
||||
|
||||
.0f<!UNSUPPORTED, UNRESOLVED_REFERENCE!>oo<!> a
|
||||
.0f<!UNSUPPORTED!>foo<!> a
|
||||
.0<!UNSUPPORTED!>doo<!> a
|
||||
.0<!UNSUPPORTED!>ddoo<!> a
|
||||
|
||||
1<!UNSUPPORTED!>in<!> a
|
||||
1.0<!UNSUPPORTED!>in<!> a
|
||||
1.0f<!UNSUPPORTED!>in<!> a
|
||||
1.0<!UNSUPPORTED, UNRESOLVED_REFERENCE!>din<!> a
|
||||
.0<!UNSUPPORTED!>in<!> a
|
||||
.0f<!UNSUPPORTED!>in<!> a
|
||||
.0<!UNSUPPORTED, UNRESOLVED_REFERENCE!>din<!> a
|
||||
|
||||
1<!UNSUPPORTED!>is<!> Any
|
||||
1<!UNSUPPORTED!>as<!> Any
|
||||
1<!UNSUPPORTED!>as?<!> Any
|
||||
|
||||
1<!UNSUPPORTED!>!is<!> Any
|
||||
1<!UNSUPPORTED!>!in<!> a
|
||||
}
|
||||
@@ -0,0 +1,9 @@
|
||||
package
|
||||
|
||||
public fun test(/*0*/ a: kotlin.Any): kotlin.Unit
|
||||
public infix fun kotlin.Any?.Loo(/*0*/ a: kotlin.Any): kotlin.Unit
|
||||
public operator fun kotlin.Any?.contains(/*0*/ a: kotlin.Any): kotlin.Boolean
|
||||
public infix fun kotlin.Any?.ddoo(/*0*/ a: kotlin.Any): kotlin.Unit
|
||||
public infix fun kotlin.Any?.doo(/*0*/ a: kotlin.Any): kotlin.Unit
|
||||
public infix fun kotlin.Any?.foo(/*0*/ a: kotlin.Any): kotlin.Unit
|
||||
public infix fun kotlin.Any?.zoo(/*0*/ a: kotlin.Any): kotlin.Unit
|
||||
@@ -403,6 +403,12 @@ public class DiagnosticsTestGenerated extends AbstractDiagnosticsTest {
|
||||
doTest(fileName);
|
||||
}
|
||||
|
||||
@TestMetadata("NumberPrefixAndSuffix.kt")
|
||||
public void testNumberPrefixAndSuffix() throws Exception {
|
||||
String fileName = KotlinTestUtils.navigationMetadata("compiler/testData/diagnostics/tests/NumberPrefixAndSuffix.kt");
|
||||
doTest(fileName);
|
||||
}
|
||||
|
||||
@TestMetadata("ObjectWithConstructor.kt")
|
||||
public void testObjectWithConstructor() throws Exception {
|
||||
String fileName = KotlinTestUtils.navigationMetadata("compiler/testData/diagnostics/tests/ObjectWithConstructor.kt");
|
||||
|
||||
Reference in New Issue
Block a user