Add SingleUnderscoreForParameterName language feature
This commit is contained in:
@@ -206,7 +206,7 @@ public class ModifiersChecker {
|
||||
for (KtDestructuringDeclarationEntry multiEntry: multiDeclaration.getEntries()) {
|
||||
annotationChecker.check(multiEntry, trace, null);
|
||||
ModifierCheckerCore.INSTANCE.check(multiEntry, trace, null, languageVersionSettings);
|
||||
UnderscoreChecker.INSTANCE.checkNamed(multiEntry, trace, /* allowSingleUnderscore = */ true);
|
||||
UnderscoreChecker.INSTANCE.checkNamed(multiEntry, trace, languageVersionSettings, /* allowSingleUnderscore = */ true);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -17,6 +17,8 @@
|
||||
package org.jetbrains.kotlin.resolve.checkers
|
||||
|
||||
import com.intellij.psi.PsiElement
|
||||
import org.jetbrains.kotlin.config.LanguageFeature
|
||||
import org.jetbrains.kotlin.config.LanguageVersionSettings
|
||||
import org.jetbrains.kotlin.descriptors.DeclarationDescriptor
|
||||
import org.jetbrains.kotlin.descriptors.VariableDescriptor
|
||||
import org.jetbrains.kotlin.descriptors.impl.FunctionExpressionDescriptor
|
||||
@@ -25,39 +27,57 @@ import org.jetbrains.kotlin.diagnostics.Errors
|
||||
import org.jetbrains.kotlin.psi.*
|
||||
import org.jetbrains.kotlin.resolve.BindingContext
|
||||
|
||||
object UnderscoreChecker : SimpleDeclarationChecker {
|
||||
object UnderscoreChecker : DeclarationChecker {
|
||||
|
||||
@JvmOverloads
|
||||
fun checkIdentifier(identifier: PsiElement?, diagnosticHolder: DiagnosticSink, allowSingleUnderscore: Boolean = false) {
|
||||
fun checkIdentifier(
|
||||
identifier: PsiElement?,
|
||||
diagnosticHolder: DiagnosticSink,
|
||||
languageVersionSettings: LanguageVersionSettings,
|
||||
allowSingleUnderscore: Boolean = false
|
||||
) {
|
||||
if (identifier == null || identifier.text.isEmpty()) return
|
||||
if (identifier.text.all { it == '_' } && (!allowSingleUnderscore || identifier.text.length != 1)) {
|
||||
val isValidSingleUnderscore = allowSingleUnderscore && identifier.text == "_"
|
||||
if (!isValidSingleUnderscore && identifier.text.all { it == '_' }) {
|
||||
diagnosticHolder.report(Errors.UNDERSCORE_IS_RESERVED.on(identifier))
|
||||
}
|
||||
else if (isValidSingleUnderscore && !languageVersionSettings.supportsFeature(LanguageFeature.SingleUnderscoreForParameterName)) {
|
||||
diagnosticHolder.report(Errors.UNSUPPORTED_FEATURE.on(identifier, LanguageFeature.SingleUnderscoreForParameterName))
|
||||
}
|
||||
}
|
||||
|
||||
@JvmOverloads
|
||||
fun checkNamed(declaration: KtNamedDeclaration, diagnosticHolder: DiagnosticSink, allowSingleUnderscore: Boolean = false) {
|
||||
checkIdentifier(declaration.nameIdentifier, diagnosticHolder, allowSingleUnderscore)
|
||||
fun checkNamed(
|
||||
declaration: KtNamedDeclaration,
|
||||
diagnosticHolder: DiagnosticSink,
|
||||
languageVersionSettings: LanguageVersionSettings,
|
||||
allowSingleUnderscore: Boolean = false
|
||||
) {
|
||||
checkIdentifier(declaration.nameIdentifier, diagnosticHolder, languageVersionSettings, allowSingleUnderscore)
|
||||
}
|
||||
|
||||
override fun check(
|
||||
declaration: KtDeclaration,
|
||||
descriptor: DeclarationDescriptor,
|
||||
diagnosticHolder: DiagnosticSink,
|
||||
bindingContext: BindingContext
|
||||
bindingContext: BindingContext,
|
||||
languageVersionSettings: LanguageVersionSettings
|
||||
) {
|
||||
if (declaration is KtProperty && descriptor !is VariableDescriptor) return
|
||||
if (declaration is KtCallableDeclaration) {
|
||||
for (parameter in declaration.valueParameters) {
|
||||
checkNamed(parameter, diagnosticHolder, allowSingleUnderscore = descriptor is FunctionExpressionDescriptor)
|
||||
checkNamed(
|
||||
parameter, diagnosticHolder, languageVersionSettings,
|
||||
allowSingleUnderscore = descriptor is FunctionExpressionDescriptor
|
||||
)
|
||||
}
|
||||
}
|
||||
if (declaration is KtTypeParameterListOwner) {
|
||||
for (typeParameter in declaration.typeParameters) {
|
||||
checkNamed(typeParameter, diagnosticHolder)
|
||||
checkNamed(typeParameter, diagnosticHolder, languageVersionSettings)
|
||||
}
|
||||
}
|
||||
if (declaration !is KtNamedDeclaration) return
|
||||
checkNamed(declaration, diagnosticHolder)
|
||||
checkNamed(declaration, diagnosticHolder, languageVersionSettings)
|
||||
}
|
||||
}
|
||||
|
||||
+1
-1
@@ -870,7 +870,7 @@ public class BasicExpressionTypingVisitor extends ExpressionTypingVisitor {
|
||||
KtSimpleNameExpression labelExpression = expression.getTargetLabel();
|
||||
if (labelExpression != null) {
|
||||
PsiElement labelIdentifier = labelExpression.getIdentifier();
|
||||
UnderscoreChecker.INSTANCE.checkIdentifier(labelIdentifier, context.trace);
|
||||
UnderscoreChecker.INSTANCE.checkIdentifier(labelIdentifier, context.trace, components.languageVersionSettings);
|
||||
}
|
||||
KtExpression baseExpression = expression.getBaseExpression();
|
||||
if (baseExpression == null) return TypeInfoFactoryKt.noTypeInfo(context);
|
||||
|
||||
+1
-1
@@ -146,7 +146,7 @@ internal class FunctionsTypingVisitor(facade: ExpressionTypingInternals) : Expre
|
||||
val functionDescriptor = createFunctionLiteralDescriptor(expression, context)
|
||||
expression.valueParameters.forEach {
|
||||
components.identifierChecker.checkDeclaration(it, context.trace)
|
||||
UnderscoreChecker.checkNamed(it, context.trace, allowSingleUnderscore = true)
|
||||
UnderscoreChecker.checkNamed(it, context.trace, components.languageVersionSettings, allowSingleUnderscore = true)
|
||||
}
|
||||
val safeReturnType = computeReturnType(expression, context, functionDescriptor, functionTypeExpected)
|
||||
functionDescriptor.setReturnType(safeReturnType)
|
||||
|
||||
@@ -0,0 +1,27 @@
|
||||
// !LANGUAGE: -SingleUnderscoreForParameterName
|
||||
|
||||
data class A(val x: Int, val y: Int)
|
||||
|
||||
fun foo(a: Array<A>) {
|
||||
val (<!UNSUPPORTED_FEATURE!>_<!>, y) = A(1, 2)
|
||||
y.hashCode()
|
||||
|
||||
val q1: (Int, String) -> Unit = {
|
||||
<!UNSUPPORTED_FEATURE!>_<!>, s -> s.hashCode()
|
||||
}
|
||||
q1(1, "")
|
||||
|
||||
val q2: (Int, String) -> Unit = fun(<!UNSUPPORTED_FEATURE!>_<!>: Int, s: String) {
|
||||
s.hashCode()
|
||||
}
|
||||
q2(1, "")
|
||||
|
||||
val q3: (A) -> Unit = {
|
||||
(<!UNSUPPORTED_FEATURE!>_<!>, y) -> y.hashCode()
|
||||
}
|
||||
q3(A(2, 3))
|
||||
|
||||
for ((<!UNSUPPORTED_FEATURE!>_<!>, z) in a) {
|
||||
z.hashCode()
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,15 @@
|
||||
package
|
||||
|
||||
public fun foo(/*0*/ a: kotlin.Array<A>): kotlin.Unit
|
||||
|
||||
public final data class A {
|
||||
public constructor A(/*0*/ x: kotlin.Int, /*1*/ y: kotlin.Int)
|
||||
public final val x: kotlin.Int
|
||||
public final val y: kotlin.Int
|
||||
public final operator /*synthesized*/ fun component1(): kotlin.Int
|
||||
public final operator /*synthesized*/ fun component2(): kotlin.Int
|
||||
public final /*synthesized*/ fun copy(/*0*/ x: kotlin.Int = ..., /*1*/ y: kotlin.Int = ...): A
|
||||
public open override /*1*/ /*synthesized*/ fun equals(/*0*/ other: kotlin.Any?): kotlin.Boolean
|
||||
public open override /*1*/ /*synthesized*/ fun hashCode(): kotlin.Int
|
||||
public open override /*1*/ /*synthesized*/ fun toString(): kotlin.String
|
||||
}
|
||||
@@ -655,6 +655,12 @@ public class DiagnosticsTestGenerated extends AbstractDiagnosticsTest {
|
||||
doTest(fileName);
|
||||
}
|
||||
|
||||
@TestMetadata("SingleUnderscoreUnsupported.kt")
|
||||
public void testSingleUnderscoreUnsupported() throws Exception {
|
||||
String fileName = KotlinTestUtils.navigationMetadata("compiler/testData/diagnostics/tests/SingleUnderscoreUnsupported.kt");
|
||||
doTest(fileName);
|
||||
}
|
||||
|
||||
@TestMetadata("StarsInFunctionCalls.kt")
|
||||
public void testStarsInFunctionCalls() throws Exception {
|
||||
String fileName = KotlinTestUtils.navigationMetadata("compiler/testData/diagnostics/tests/StarsInFunctionCalls.kt");
|
||||
|
||||
@@ -29,6 +29,7 @@ enum class LanguageFeature(val sinceVersion: LanguageVersion) {
|
||||
DataClassInheritance(KOTLIN_1_1),
|
||||
InlineProperties(KOTLIN_1_1),
|
||||
DestructuringLambdaParameters(KOTLIN_1_1),
|
||||
SingleUnderscoreForParameterName(KOTLIN_1_1)
|
||||
;
|
||||
|
||||
val presentableText: String
|
||||
|
||||
Reference in New Issue
Block a user