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> WRONG_MODIFIER_CONTAINING_DECLARATION = DiagnosticFactory2.create(ERROR);
|
||||
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);
|
||||
DiagnosticFactory2<JetAnnotationEntry, String, String> WRONG_ANNOTATION_TARGET_WITH_USE_SITE_TARGET = DiagnosticFactory2.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(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(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_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");
|
||||
|
||||
@@ -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(),
|
||||
ConstModifierChecker,
|
||||
UnderscoreChecker,
|
||||
InlineParameterChecker,
|
||||
OperatorModifierChecker(),
|
||||
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);
|
||||
}
|
||||
|
||||
@TestMetadata("inlineParameters.kt")
|
||||
public void testInlineParameters() throws Exception {
|
||||
String fileName = JetTestUtils.navigationMetadata("compiler/testData/diagnostics/tests/modifiers/inlineParameters.kt");
|
||||
doTest(fileName);
|
||||
}
|
||||
|
||||
@TestMetadata("internalInInterface.kt")
|
||||
public void testInternalInInterface() throws Exception {
|
||||
String fileName = JetTestUtils.navigationMetadata("compiler/testData/diagnostics/tests/modifiers/internalInInterface.kt");
|
||||
|
||||
Reference in New Issue
Block a user