Improve inline diagnostics, report "nothing to inline" on the modifier

This commit is contained in:
Alexander Udalov
2015-09-14 13:02:12 +03:00
parent a946f787bc
commit b4470de713
9 changed files with 27 additions and 22 deletions
@@ -672,7 +672,7 @@ public interface Errors {
DiagnosticFactory2<JetElement, DeclarationDescriptor, DeclarationDescriptor> INVISIBLE_MEMBER_FROM_INLINE = DiagnosticFactory2.create(ERROR, CALL_ELEMENT);
DiagnosticFactory3<JetElement, JetElement, DeclarationDescriptor, DeclarationDescriptor> NON_LOCAL_RETURN_NOT_ALLOWED = DiagnosticFactory3.create(ERROR, CALL_ELEMENT);
DiagnosticFactory2<JetElement, JetNamedDeclaration, DeclarationDescriptor> NOT_YET_SUPPORTED_IN_INLINE = DiagnosticFactory2.create(ERROR);
DiagnosticFactory1<JetFunction, DeclarationDescriptor> NOTHING_TO_INLINE = DiagnosticFactory1.create(WARNING, DECLARATION_SIGNATURE);
DiagnosticFactory1<PsiElement, DeclarationDescriptor> NOTHING_TO_INLINE = DiagnosticFactory1.create(WARNING);
DiagnosticFactory2<JetElement, JetExpression, DeclarationDescriptor> USAGE_IS_NOT_INLINABLE = DiagnosticFactory2.create(ERROR);
DiagnosticFactory2<JetElement, JetElement, DeclarationDescriptor> NULLABLE_INLINE_PARAMETER = DiagnosticFactory2.create(ERROR);
DiagnosticFactory2<JetElement, JetElement, DeclarationDescriptor> RECURSION_IN_INLINE = DiagnosticFactory2.create(ERROR);
@@ -622,14 +622,14 @@ public class DefaultErrorMessages {
MAP.put(ARRAY_CLASS_LITERAL_REQUIRES_ARGUMENT, "kotlin.Array class literal requires a type argument, please specify one in angle brackets");
//Inline
MAP.put(INVISIBLE_MEMBER_FROM_INLINE, "Cannot access effectively non-public-api ''{0}'' member from effectively public-api ''{1}''", SHORT_NAMES_IN_TYPES, SHORT_NAMES_IN_TYPES);
MAP.put(NOT_YET_SUPPORTED_IN_INLINE, "''{0}'' construction not yet supported in inline functions", ELEMENT_TEXT, SHORT_NAMES_IN_TYPES);
MAP.put(DECLARATION_CANT_BE_INLINED, "Inline annotation could be present only on nonvirtual members (private or final)");
MAP.put(INVISIBLE_MEMBER_FROM_INLINE, "Cannot access effectively non-public-API ''{0}'' member from effectively public-API ''{1}''", SHORT_NAMES_IN_TYPES, SHORT_NAMES_IN_TYPES);
MAP.put(NOT_YET_SUPPORTED_IN_INLINE, "''{0}'' construction is not yet supported in inline functions", ELEMENT_TEXT, SHORT_NAMES_IN_TYPES);
MAP.put(DECLARATION_CANT_BE_INLINED, "''inline'' modifier is not allowed on virtual members. Only private or final members can be inlined");
MAP.put(NOTHING_TO_INLINE, "Expected performance impact of inlining ''{0}'' can be insignificant. Inlining works best for functions with lambda parameters", SHORT_NAMES_IN_TYPES);
MAP.put(USAGE_IS_NOT_INLINABLE, "Illegal usage of inline-parameter ''{0}'' in ''{1}''. Annotate the parameter with [noinline]", ELEMENT_TEXT, SHORT_NAMES_IN_TYPES);
MAP.put(NULLABLE_INLINE_PARAMETER, "Inline-parameter ''{0}'' of ''{1}'' must not be nullable. Annotate the parameter with [noinline] or make not nullable", ELEMENT_TEXT, SHORT_NAMES_IN_TYPES);
MAP.put(RECURSION_IN_INLINE, "Inline-function ''{1}'' can't be recursive", ELEMENT_TEXT, SHORT_NAMES_IN_TYPES);
//Inline non Locals
MAP.put(USAGE_IS_NOT_INLINABLE, "Illegal usage of inline-parameter ''{0}'' in ''{1}''. Add ''noinline'' modifier to the parameter declaration", ELEMENT_TEXT, SHORT_NAMES_IN_TYPES);
MAP.put(NULLABLE_INLINE_PARAMETER, "Inline-parameter ''{0}'' of ''{1}'' must not be nullable. Add ''noinline'' modifier to the parameter declaration or make its type not nullable", ELEMENT_TEXT, SHORT_NAMES_IN_TYPES);
MAP.put(RECURSION_IN_INLINE, "Inline function ''{1}'' can't be recursive", ELEMENT_TEXT, SHORT_NAMES_IN_TYPES);
//Inline non locals
MAP.put(NON_LOCAL_RETURN_NOT_ALLOWED, "Can''t inline ''{0}'' here: it may contain non-local returns. Add ''crossinline'' modifier to parameter declaration ''{0}''", ELEMENT_TEXT, SHORT_NAMES_IN_TYPES, SHORT_NAMES_IN_TYPES);
MAP.put(INLINE_CALL_CYCLE, "The ''{0}'' invocation is a part of inline cycle", NAME);
MAP.put(NON_LOCAL_RETURN_IN_DISABLED_INLINE, "Non-local returns are not allowed with inlining disabled");
@@ -16,10 +16,12 @@
package org.jetbrains.kotlin.resolve.inline;
import com.intellij.psi.PsiElement;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
import org.jetbrains.kotlin.descriptors.*;
import org.jetbrains.kotlin.diagnostics.Errors;
import org.jetbrains.kotlin.lexer.JetTokens;
import org.jetbrains.kotlin.psi.*;
import org.jetbrains.kotlin.resolve.BindingTrace;
import org.jetbrains.kotlin.resolve.DescriptorUtils;
@@ -125,7 +127,10 @@ public class InlineAnalyzerExtension implements FunctionAnalyzerExtension.Analyz
hasInlinable |= DescriptorUtils.containsReifiedTypeParameters(functionDescriptor);
if (!hasInlinable) {
trace.report(Errors.NOTHING_TO_INLINE.on(function, functionDescriptor));
JetModifierList modifierList = function.getModifierList();
PsiElement inlineModifier = modifierList == null ? null : modifierList.getModifier(JetTokens.INLINE_KEYWORD);
PsiElement reportOn = inlineModifier == null ? function : inlineModifier;
trace.report(Errors.NOTHING_TO_INLINE.on(reportOn, functionDescriptor));
}
}
@@ -2,6 +2,6 @@ inline fun <R> onlyLocal(p: () -> R) {
inlineAll(<!USAGE_IS_NOT_INLINABLE!>p<!>)
}
<!NOTHING_TO_INLINE!>inline fun <R> inlineAll(noinline p: () -> R)<!> {
<!NOTHING_TO_INLINE!>inline<!> fun <R> inlineAll(noinline p: () -> R) {
p()
}
@@ -6,6 +6,6 @@ fun box() : String {
return "OK"
}
<!NOTHING_TO_INLINE!>inline fun <T> test(p: T)<!> {
<!NOTHING_TO_INLINE!>inline<!> fun <T> test(p: T) {
p.toString()
}
@@ -6,6 +6,6 @@ fun box() : String {
return "OK"
}
<!NOTHING_TO_INLINE!>inline fun test(p: Any)<!> {
<!NOTHING_TO_INLINE!>inline<!> fun test(p: Any) {
p.toString()
}
@@ -1,6 +1,6 @@
// !DIAGNOSTICS: -UNUSED_EXPRESSION -UNUSED_PARAMETER -UNUSED_VARIABLE -NULLABLE_INLINE_PARAMETER -CONFLICTING_JVM_DECLARATIONS
<!NOTHING_TO_INLINE!>inline fun test()<!> {
<!NOTHING_TO_INLINE!>inline<!> fun test() {
}
@@ -8,22 +8,22 @@ inline fun test2(s : (Int) -> Int) {
}
<!NOTHING_TO_INLINE!>inline fun test3(noinline s : (Int) -> Int)<!> {
<!NOTHING_TO_INLINE!>inline<!> fun test3(noinline s : (Int) -> Int) {
}
<!NOTHING_TO_INLINE!>inline fun test4(noinline s : Int.() -> Int)<!> {
<!NOTHING_TO_INLINE!>inline<!> fun test4(noinline s : Int.() -> Int) {
}
<!NOTHING_TO_INLINE!>inline fun Function1<Int, Int>?.test5()<!> {
<!NOTHING_TO_INLINE!>inline<!> fun Function1<Int, Int>?.test5() {
}
<!NOTHING_TO_INLINE!>inline fun Function1<Int, Int>?.test6()<!> {
<!NOTHING_TO_INLINE!>inline<!> fun Function1<Int, Int>?.test6() {
}
<!NOTHING_TO_INLINE!>inline fun test2(s : ((Int) -> Int)?)<!> {
<!NOTHING_TO_INLINE!>inline<!> fun test2(s : ((Int) -> Int)?) {
}
@@ -12,10 +12,10 @@ public inline fun <T> submitNoInline(noinline action: Function1<Int, Int>?, s: (
action?.invoke(10)
}
<!NOTHING_TO_INLINE!>public inline fun <T> <!NULLABLE_INLINE_PARAMETER!>Function1<Int, Int>?<!>.submit()<!> {
public <!NOTHING_TO_INLINE!>inline<!> fun <T> <!NULLABLE_INLINE_PARAMETER!>Function1<Int, Int>?<!>.submit() {
}
<!NOTHING_TO_INLINE!>public inline fun <T> submit(<!NULLABLE_INLINE_PARAMETER!>action: Function1<Int, Int>?<!>)<!> {
public <!NOTHING_TO_INLINE!>inline<!> fun <T> submit(<!NULLABLE_INLINE_PARAMETER!>action: Function1<Int, Int>?<!>) {
}
@@ -1,11 +1,11 @@
import kotlin.jvm.*
abstract class C {
<!EXTERNAL_DECLARATION_CANNOT_BE_INLINED, NOTHING_TO_INLINE!>inline external fun foo()<!>
<!EXTERNAL_DECLARATION_CANNOT_BE_INLINED!><!NOTHING_TO_INLINE!>inline<!> external fun foo()<!>
}
fun test() {
abstract class Local {
<!EXTERNAL_DECLARATION_CANNOT_BE_INLINED, NOTHING_TO_INLINE!>inline external fun foo()<!>
<!EXTERNAL_DECLARATION_CANNOT_BE_INLINED!><!NOTHING_TO_INLINE!>inline<!> external fun foo()<!>
}
}