Create warning for old lambda syntax.
This commit is contained in:
@@ -346,6 +346,9 @@ public interface Errors {
|
||||
|
||||
DiagnosticFactory0<JetParameter> USELESS_VARARG_ON_PARAMETER = DiagnosticFactory0.create(WARNING);
|
||||
|
||||
DiagnosticFactory0<JetFunctionLiteralExpression> DEPRECATED_LAMBDA_SYNTAX =
|
||||
DiagnosticFactory0.create(WARNING, FUNCTION_LITERAL_EXPRESSION_DECLARATION);
|
||||
|
||||
// Named parameters
|
||||
|
||||
DiagnosticFactory0<JetParameter> DEFAULT_VALUE_NOT_ALLOWED_IN_OVERRIDE = DiagnosticFactory0.create(ERROR, PARAMETER_DEFAULT_VALUE);
|
||||
|
||||
@@ -34,7 +34,7 @@ public object PositioningStrategies {
|
||||
if (element is JetNamedDeclaration &&
|
||||
element !is JetObjectDeclaration &&
|
||||
element !is JetSecondaryConstructor &&
|
||||
element !is JetNamedFunction
|
||||
element !is JetFunction
|
||||
) {
|
||||
if (element.getNameIdentifier() == null) {
|
||||
return false
|
||||
@@ -115,14 +115,20 @@ public object PositioningStrategies {
|
||||
public val DECLARATION_SIGNATURE: PositioningStrategy<JetDeclaration> = object : DeclarationHeader<JetDeclaration>() {
|
||||
override fun mark(element: JetDeclaration): List<TextRange> {
|
||||
when (element) {
|
||||
is JetNamedFunction -> {
|
||||
is JetFunction -> {
|
||||
val endOfSignatureElement =
|
||||
element.getTypeReference()
|
||||
?: element.getValueParameterList()
|
||||
?: element.getNameIdentifier()
|
||||
?: element
|
||||
|
||||
return markRange(element, endOfSignatureElement)
|
||||
val startElement
|
||||
= if (element is JetFunctionLiteral) {
|
||||
element.getReceiverTypeReference()
|
||||
?: element.getValueParameterList()
|
||||
?: element
|
||||
}
|
||||
else element
|
||||
return markRange(startElement, endOfSignatureElement)
|
||||
}
|
||||
is JetProperty -> {
|
||||
val endOfSignatureElement = element.getTypeReference() ?: element.getNameIdentifier() ?: element
|
||||
@@ -168,6 +174,12 @@ public object PositioningStrategies {
|
||||
}
|
||||
}
|
||||
|
||||
public val FUNCTION_LITERAL_EXPRESSION_DECLARATION: PositioningStrategy<JetFunctionLiteralExpression>
|
||||
= object : PositioningStrategy<JetFunctionLiteralExpression>() {
|
||||
override fun mark(element: JetFunctionLiteralExpression) = DECLARATION_SIGNATURE_OR_DEFAULT.mark(element.getFunctionLiteral())
|
||||
override fun isValid(element: JetFunctionLiteralExpression) = DECLARATION_SIGNATURE_OR_DEFAULT.isValid(element.getFunctionLiteral())
|
||||
}
|
||||
|
||||
public val TYPE_PARAMETERS_OR_DECLARATION_SIGNATURE: PositioningStrategy<JetDeclaration> = object : PositioningStrategy<JetDeclaration>() {
|
||||
override fun mark(element: JetDeclaration): List<TextRange> {
|
||||
if (element is JetTypeParameterListOwner) {
|
||||
|
||||
+2
@@ -230,6 +230,8 @@ public class DefaultErrorMessages {
|
||||
|
||||
MAP.put(FUNCTION_EXPRESSION_PARAMETER_WITH_DEFAULT_VALUE, "A function expression is not allowed to specify default values for its parameters");
|
||||
MAP.put(USELESS_VARARG_ON_PARAMETER, "Vararg on this parameter is useless");
|
||||
MAP.put(DEPRECATED_LAMBDA_SYNTAX,
|
||||
"This syntax for lambda is deprecated. Use short lambda notation {a[: Int], b[: String] -> ...} or function expression instead.");
|
||||
|
||||
MAP.put(PROJECTION_ON_NON_CLASS_TYPE_ARGUMENT, "Projections are not allowed on type arguments of functions and properties");
|
||||
MAP.put(SUPERTYPE_NOT_INITIALIZED, "This type has a constructor, and thus must be initialized here");
|
||||
|
||||
@@ -17,7 +17,9 @@
|
||||
package org.jetbrains.kotlin.psi;
|
||||
|
||||
import com.intellij.lang.ASTNode;
|
||||
import com.intellij.psi.PsiElement;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
import org.jetbrains.kotlin.lexer.JetTokens;
|
||||
import org.jetbrains.kotlin.psi.stubs.KotlinPlaceHolderStub;
|
||||
import org.jetbrains.kotlin.psi.stubs.elements.JetStubElementTypes;
|
||||
|
||||
@@ -41,4 +43,14 @@ public class JetParameterList extends JetElementImplStub<KotlinPlaceHolderStub<J
|
||||
public List<JetParameter> getParameters() {
|
||||
return getStubOrPsiChildrenAsList(JetStubElementTypes.VALUE_PARAMETER);
|
||||
}
|
||||
|
||||
// this method needed only for migrate lambda syntax
|
||||
@Deprecated
|
||||
public boolean isParenthesized() {
|
||||
PsiElement firstChild = getFirstChild();
|
||||
if (firstChild != null && firstChild.getNode() != null) {
|
||||
return firstChild.getNode().getElementType() == JetTokens.LPAR;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -911,4 +911,14 @@ public class JetPsiUtil {
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
public static boolean isDeprecatedLambdaSyntax(@NotNull JetFunctionLiteralExpression functionLiteralExpression) {
|
||||
JetFunctionLiteral functionLiteral = functionLiteralExpression.getFunctionLiteral();
|
||||
if (functionLiteral.hasDeclaredReturnType() || functionLiteral.getReceiverTypeReference() != null) return true;
|
||||
|
||||
JetParameterList valueParameterList = functionLiteral.getValueParameterList();
|
||||
if (valueParameterList != null && valueParameterList.isParenthesized()) return true;
|
||||
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -124,6 +124,10 @@ public class FunctionsTypingVisitor(facade: ExpressionTypingInternals) : Express
|
||||
override fun visitFunctionLiteralExpression(expression: JetFunctionLiteralExpression, context: ExpressionTypingContext): JetTypeInfo? {
|
||||
if (!expression.getFunctionLiteral().hasBody()) return null
|
||||
|
||||
if (JetPsiUtil.isDeprecatedLambdaSyntax(expression)) {
|
||||
context.trace.report(DEPRECATED_LAMBDA_SYNTAX.on(expression))
|
||||
}
|
||||
|
||||
val expectedType = context.expectedType
|
||||
val functionTypeExpected = !noExpectedType(expectedType) && KotlinBuiltIns.isFunctionOrExtensionFunctionType(expectedType)
|
||||
|
||||
|
||||
@@ -0,0 +1,24 @@
|
||||
val receiver = { <!DEPRECATED_LAMBDA_SYNTAX!>Int.()<!> -> }
|
||||
val receiverWithParameter = { <!DEPRECATED_LAMBDA_SYNTAX!>Int.(<!CANNOT_INFER_PARAMETER_TYPE!>a<!>)<!> -> }
|
||||
|
||||
val receiverAndReturnType = { <!DEPRECATED_LAMBDA_SYNTAX!>Int.(): Int<!> -> 5 }
|
||||
val receiverAndReturnTypeWithParameter = { <!DEPRECATED_LAMBDA_SYNTAX!>Int.(a: Int): Int<!> -> 5 }
|
||||
|
||||
val returnType = { <!DEPRECATED_LAMBDA_SYNTAX!>(): Int<!> -> 5 }
|
||||
val returnTypeWithParameter = { <!DEPRECATED_LAMBDA_SYNTAX!>(b: Int): Int<!> -> 5 }
|
||||
|
||||
val receiverWithFunctionType = { <!DEPRECATED_LAMBDA_SYNTAX!>((Int) -> Int).()<!> -> }
|
||||
|
||||
val parenthesizedParameters = { <!DEPRECATED_LAMBDA_SYNTAX!>(a: Int)<!> -> }
|
||||
val parenthesizedParameters2 = { <!DEPRECATED_LAMBDA_SYNTAX!>(<!CANNOT_INFER_PARAMETER_TYPE!>b<!>)<!> -> }
|
||||
|
||||
val none = { -> }
|
||||
|
||||
|
||||
val parameterWithFunctionType = { <!UNRESOLVED_REFERENCE!>a<!>: ((Int) -> Int) -> <!SYNTAX!><!>} // todo fix parser
|
||||
|
||||
val newSyntax = { a: Int -> }
|
||||
val newSyntax1 = { <!CANNOT_INFER_PARAMETER_TYPE!>a<!>, <!CANNOT_INFER_PARAMETER_TYPE!>b<!> -> }
|
||||
val newSyntax2 = { a: Int, b: Int -> }
|
||||
val newSyntax3 = { <!CANNOT_INFER_PARAMETER_TYPE!>a<!>, b: Int -> }
|
||||
val newSyntax4 = { a: Int, <!CANNOT_INFER_PARAMETER_TYPE!>b<!> -> }
|
||||
@@ -0,0 +1,18 @@
|
||||
package
|
||||
|
||||
internal val newSyntax: (kotlin.Int) -> kotlin.Unit
|
||||
internal val newSyntax1: (???, ???) -> kotlin.Unit
|
||||
internal val newSyntax2: (kotlin.Int, kotlin.Int) -> kotlin.Unit
|
||||
internal val newSyntax3: (???, kotlin.Int) -> kotlin.Unit
|
||||
internal val newSyntax4: (kotlin.Int, ???) -> kotlin.Unit
|
||||
internal val none: () -> kotlin.Unit
|
||||
internal val parameterWithFunctionType: () -> ((kotlin.Int) -> kotlin.Int) -> [ERROR : No type element]
|
||||
internal val parenthesizedParameters: (kotlin.Int) -> kotlin.Unit
|
||||
internal val parenthesizedParameters2: (???) -> kotlin.Unit
|
||||
internal val receiver: kotlin.Int.() -> kotlin.Unit
|
||||
internal val receiverAndReturnType: kotlin.Int.() -> kotlin.Int
|
||||
internal val receiverAndReturnTypeWithParameter: kotlin.Int.(kotlin.Int) -> kotlin.Int
|
||||
internal val receiverWithFunctionType: (kotlin.Int) -> kotlin.Int.() -> kotlin.Unit
|
||||
internal val receiverWithParameter: kotlin.Int.(???) -> kotlin.Unit
|
||||
internal val returnType: () -> kotlin.Int
|
||||
internal val returnTypeWithParameter: (kotlin.Int) -> kotlin.Int
|
||||
@@ -4754,6 +4754,12 @@ public class JetDiagnosticsTestGenerated extends AbstractJetDiagnosticsTest {
|
||||
doTest(fileName);
|
||||
}
|
||||
|
||||
@TestMetadata("DeprecatedSyntax.kt")
|
||||
public void testDeprecatedSyntax() throws Exception {
|
||||
String fileName = JetTestUtils.navigationMetadata("compiler/testData/diagnostics/tests/functionLiterals/DeprecatedSyntax.kt");
|
||||
doTest(fileName);
|
||||
}
|
||||
|
||||
@TestMetadata("ExpectedParameterTypeMismatchVariance.kt")
|
||||
public void testExpectedParameterTypeMismatchVariance() throws Exception {
|
||||
String fileName = JetTestUtils.navigationMetadata("compiler/testData/diagnostics/tests/functionLiterals/ExpectedParameterTypeMismatchVariance.kt");
|
||||
|
||||
Reference in New Issue
Block a user