Additional correctness check for noinline & crossinline #KT-9567 Fixed
This commit is contained in:
@@ -125,6 +125,7 @@ public interface Errors {
|
|||||||
DiagnosticFactory2<PsiElement, JetModifierKeywordToken, String> REDUNDANT_MODIFIER_FOR_TARGET = DiagnosticFactory2.create(WARNING);
|
DiagnosticFactory2<PsiElement, JetModifierKeywordToken, String> REDUNDANT_MODIFIER_FOR_TARGET = DiagnosticFactory2.create(WARNING);
|
||||||
DiagnosticFactory2<PsiElement, JetModifierKeywordToken, String> WRONG_MODIFIER_CONTAINING_DECLARATION = DiagnosticFactory2.create(ERROR);
|
DiagnosticFactory2<PsiElement, JetModifierKeywordToken, String> WRONG_MODIFIER_CONTAINING_DECLARATION = DiagnosticFactory2.create(ERROR);
|
||||||
DiagnosticFactory2<PsiElement, JetModifierKeywordToken, String> DEPRECATED_MODIFIER_CONTAINING_DECLARATION = DiagnosticFactory2.create(WARNING);
|
DiagnosticFactory2<PsiElement, JetModifierKeywordToken, String> DEPRECATED_MODIFIER_CONTAINING_DECLARATION = DiagnosticFactory2.create(WARNING);
|
||||||
|
DiagnosticFactory1<PsiElement, JetModifierKeywordToken> ILLEGAL_INLINE_PARAMETER_MODIFIER = DiagnosticFactory1.create(ERROR);
|
||||||
DiagnosticFactory1<JetAnnotationEntry, String> WRONG_ANNOTATION_TARGET = DiagnosticFactory1.create(ERROR);
|
DiagnosticFactory1<JetAnnotationEntry, String> WRONG_ANNOTATION_TARGET = DiagnosticFactory1.create(ERROR);
|
||||||
DiagnosticFactory2<JetAnnotationEntry, String, String> WRONG_ANNOTATION_TARGET_WITH_USE_SITE_TARGET = DiagnosticFactory2.create(ERROR);
|
DiagnosticFactory2<JetAnnotationEntry, String, String> WRONG_ANNOTATION_TARGET_WITH_USE_SITE_TARGET = DiagnosticFactory2.create(ERROR);
|
||||||
DiagnosticFactory0<JetAnnotationEntry> REPEATED_ANNOTATION = DiagnosticFactory0.create(ERROR);
|
DiagnosticFactory0<JetAnnotationEntry> REPEATED_ANNOTATION = DiagnosticFactory0.create(ERROR);
|
||||||
|
|||||||
+1
@@ -132,6 +132,7 @@ public class DefaultErrorMessages {
|
|||||||
MAP.put(REDUNDANT_MODIFIER_FOR_TARGET, "Modifier ''{0}'' is redundant for ''{1}''", TO_STRING, TO_STRING);
|
MAP.put(REDUNDANT_MODIFIER_FOR_TARGET, "Modifier ''{0}'' is redundant for ''{1}''", TO_STRING, TO_STRING);
|
||||||
MAP.put(WRONG_MODIFIER_CONTAINING_DECLARATION, "Modifier ''{0}'' is not applicable inside ''{1}''", TO_STRING, TO_STRING);
|
MAP.put(WRONG_MODIFIER_CONTAINING_DECLARATION, "Modifier ''{0}'' is not applicable inside ''{1}''", TO_STRING, TO_STRING);
|
||||||
MAP.put(DEPRECATED_MODIFIER_CONTAINING_DECLARATION, "Modifier ''{0}'' is deprecated inside ''{1}''", TO_STRING, TO_STRING);
|
MAP.put(DEPRECATED_MODIFIER_CONTAINING_DECLARATION, "Modifier ''{0}'' is deprecated inside ''{1}''", TO_STRING, TO_STRING);
|
||||||
|
MAP.put(ILLEGAL_INLINE_PARAMETER_MODIFIER, "Modifier ''{0}'' is allowed only for function parameters of an inline function", TO_STRING);
|
||||||
MAP.put(WRONG_ANNOTATION_TARGET, "This annotation is not applicable to target ''{0}''", TO_STRING);
|
MAP.put(WRONG_ANNOTATION_TARGET, "This annotation is not applicable to target ''{0}''", TO_STRING);
|
||||||
MAP.put(WRONG_ANNOTATION_TARGET_WITH_USE_SITE_TARGET, "This annotation is not applicable to target ''{0}'' and use site target ''@{1}''", TO_STRING, TO_STRING);
|
MAP.put(WRONG_ANNOTATION_TARGET_WITH_USE_SITE_TARGET, "This annotation is not applicable to target ''{0}'' and use site target ''@{1}''", TO_STRING, TO_STRING);
|
||||||
MAP.put(REPEATED_ANNOTATION, "This annotation is not repeatable");
|
MAP.put(REPEATED_ANNOTATION, "This annotation is not repeatable");
|
||||||
|
|||||||
@@ -0,0 +1,53 @@
|
|||||||
|
/*
|
||||||
|
* Copyright 2010-2015 JetBrains s.r.o.
|
||||||
|
*
|
||||||
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
|
* you may not use this file except in compliance with the License.
|
||||||
|
* You may obtain a copy of the License at
|
||||||
|
*
|
||||||
|
* http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
*
|
||||||
|
* Unless required by applicable law or agreed to in writing, software
|
||||||
|
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
|
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
|
* See the License for the specific language governing permissions and
|
||||||
|
* limitations under the License.
|
||||||
|
*/
|
||||||
|
|
||||||
|
package org.jetbrains.kotlin.resolve
|
||||||
|
|
||||||
|
import org.jetbrains.kotlin.builtins.KotlinBuiltIns
|
||||||
|
import org.jetbrains.kotlin.descriptors.DeclarationDescriptor
|
||||||
|
import org.jetbrains.kotlin.diagnostics.DiagnosticSink
|
||||||
|
import org.jetbrains.kotlin.diagnostics.Errors
|
||||||
|
import org.jetbrains.kotlin.lexer.JetModifierKeywordToken
|
||||||
|
import org.jetbrains.kotlin.lexer.JetTokens
|
||||||
|
import org.jetbrains.kotlin.psi.JetDeclaration
|
||||||
|
import org.jetbrains.kotlin.psi.JetFunction
|
||||||
|
import org.jetbrains.kotlin.psi.JetParameter
|
||||||
|
|
||||||
|
object InlineParameterChecker : DeclarationChecker {
|
||||||
|
override fun check(declaration: JetDeclaration,
|
||||||
|
descriptor: DeclarationDescriptor,
|
||||||
|
diagnosticHolder: DiagnosticSink,
|
||||||
|
bindingContext: BindingContext
|
||||||
|
) {
|
||||||
|
if (declaration is JetFunction) {
|
||||||
|
val inline = declaration.hasModifier(JetTokens.INLINE_KEYWORD)
|
||||||
|
for (parameter in declaration.valueParameters) {
|
||||||
|
val parameterDescriptor = bindingContext.get(BindingContext.VALUE_PARAMETER, parameter)
|
||||||
|
if (!inline || (parameterDescriptor != null && !KotlinBuiltIns.isFunctionOrExtensionFunctionType(parameterDescriptor.type))) {
|
||||||
|
parameter.reportIncorrectInline(JetTokens.NOINLINE_KEYWORD, diagnosticHolder)
|
||||||
|
parameter.reportIncorrectInline(JetTokens.CROSSINLINE_KEYWORD, diagnosticHolder)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private fun JetParameter.reportIncorrectInline(modifierToken: JetModifierKeywordToken, diagnosticHolder: DiagnosticSink) {
|
||||||
|
val modifier = modifierList?.getModifier(modifierToken)
|
||||||
|
modifier?.let {
|
||||||
|
diagnosticHolder.report(Errors.ILLEGAL_INLINE_PARAMETER_MODIFIER.on(modifier, modifierToken))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -51,6 +51,7 @@ private val DEFAULT_DECLARATION_CHECKERS = listOf(
|
|||||||
DataClassAnnotationChecker(),
|
DataClassAnnotationChecker(),
|
||||||
ConstModifierChecker,
|
ConstModifierChecker,
|
||||||
UnderscoreChecker,
|
UnderscoreChecker,
|
||||||
|
InlineParameterChecker,
|
||||||
OperatorModifierChecker(),
|
OperatorModifierChecker(),
|
||||||
InfixModifierChecker())
|
InfixModifierChecker())
|
||||||
|
|
||||||
|
|||||||
@@ -0,0 +1,10 @@
|
|||||||
|
// !DIAGNOSTICS: -UNUSED_PARAMETER
|
||||||
|
|
||||||
|
<!NOTHING_TO_INLINE!>inline<!> fun foo(<!ILLEGAL_INLINE_PARAMETER_MODIFIER!>noinline<!> x: Int) {}
|
||||||
|
|
||||||
|
<!NOTHING_TO_INLINE!>inline<!> fun bar(y: Int, <!ILLEGAL_INLINE_PARAMETER_MODIFIER!>crossinline<!> x: String) {}
|
||||||
|
|
||||||
|
fun gav(<!ILLEGAL_INLINE_PARAMETER_MODIFIER!>noinline<!> x: (Int) -> Unit, <!ILLEGAL_INLINE_PARAMETER_MODIFIER!>crossinline<!> y: (String) -> Int) {}
|
||||||
|
|
||||||
|
inline fun correct(noinline x: (Int) -> Unit, crossinline y: (String) -> Int) {}
|
||||||
|
|
||||||
@@ -0,0 +1,6 @@
|
|||||||
|
package
|
||||||
|
|
||||||
|
@kotlin.inline() public fun bar(/*0*/ y: kotlin.Int, /*1*/ @kotlin.crossinline() x: kotlin.String): kotlin.Unit
|
||||||
|
@kotlin.inline() public fun correct(/*0*/ @kotlin.noinline() x: (kotlin.Int) -> kotlin.Unit, /*1*/ @kotlin.crossinline() y: (kotlin.String) -> kotlin.Int): kotlin.Unit
|
||||||
|
@kotlin.inline() public fun foo(/*0*/ @kotlin.noinline() x: kotlin.Int): kotlin.Unit
|
||||||
|
public fun gav(/*0*/ @kotlin.noinline() x: (kotlin.Int) -> kotlin.Unit, /*1*/ @kotlin.crossinline() y: (kotlin.String) -> kotlin.Int): kotlin.Unit
|
||||||
@@ -9430,6 +9430,12 @@ public class JetDiagnosticsTestGenerated extends AbstractJetDiagnosticsTest {
|
|||||||
doTest(fileName);
|
doTest(fileName);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@TestMetadata("inlineParameters.kt")
|
||||||
|
public void testInlineParameters() throws Exception {
|
||||||
|
String fileName = JetTestUtils.navigationMetadata("compiler/testData/diagnostics/tests/modifiers/inlineParameters.kt");
|
||||||
|
doTest(fileName);
|
||||||
|
}
|
||||||
|
|
||||||
@TestMetadata("internalInInterface.kt")
|
@TestMetadata("internalInInterface.kt")
|
||||||
public void testInternalInInterface() throws Exception {
|
public void testInternalInInterface() throws Exception {
|
||||||
String fileName = JetTestUtils.navigationMetadata("compiler/testData/diagnostics/tests/modifiers/internalInInterface.kt");
|
String fileName = JetTestUtils.navigationMetadata("compiler/testData/diagnostics/tests/modifiers/internalInInterface.kt");
|
||||||
|
|||||||
Reference in New Issue
Block a user