Diagnostics for wrong inlinable usage

This commit is contained in:
Mikhael Bogdanov
2013-11-29 16:22:31 +04:00
parent ac6dc9fa54
commit c89c465fec
18 changed files with 635 additions and 8 deletions
@@ -560,6 +560,13 @@ public interface Errors {
DiagnosticFactory1<PsiElement, ClassDescriptor> INACCESSIBLE_OUTER_CLASS_EXPRESSION = DiagnosticFactory1.create(ERROR);
DiagnosticFactory0<PsiElement> NESTED_CLASS_NOT_ALLOWED = DiagnosticFactory0.create(ERROR);
//Inline and inlinable parameters
DiagnosticFactory2<JetElement, DeclarationDescriptor, DeclarationDescriptor> INVISIBLE_MEMBER_FROM_INLINE = DiagnosticFactory2.create(ERROR, CALL_ELEMENT);
DiagnosticFactory2<JetElement, JetNamedDeclaration, DeclarationDescriptor> NOT_YET_SUPPORTED_IN_INLINE = DiagnosticFactory2.create(ERROR);
DiagnosticFactory1<JetElement, 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);
DiagnosticFactory0<JetElement> DECLARATION_CANT_BE_INLINED = DiagnosticFactory0.create(ERROR);
// Error sets
ImmutableSet<? extends DiagnosticFactory> UNRESOLVED_REFERENCE_DIAGNOSTICS = ImmutableSet.of(
@@ -33,6 +33,7 @@ import java.lang.reflect.Modifier;
import java.util.Collection;
import static org.jetbrains.jet.lang.diagnostics.Errors.*;
import static org.jetbrains.jet.lang.diagnostics.Errors.DECLARATION_CANT_BE_INLINED;
import static org.jetbrains.jet.lang.diagnostics.rendering.Renderers.*;
public class DefaultErrorMessages {
@@ -471,6 +472,14 @@ public class DefaultErrorMessages {
"''{0}'' is a member and an extension at the same time. References to such elements are not allowed", TO_STRING);
MAP.put(CALLABLE_REFERENCE_LHS_NOT_A_CLASS, "Callable reference left-hand side cannot be a type parameter");
//Inline
MAP.put(INVISIBLE_MEMBER_FROM_INLINE, "Cannot access effectively non-public-api ''{0}'' member from effectively public-api ''{1}''", TO_STRING, TO_STRING);
MAP.put(NOT_YET_SUPPORTED_IN_INLINE, "''{0}'' construction not yet supported in inline functions", ELEMENT_TEXT, TO_STRING);
MAP.put(DECLARATION_CANT_BE_INLINED, "Inline annotation could be present only on nonvirtual members (private or final)");
MAP.put(NOTHING_TO_INLINE, "There are no parameters of Function types to be inlined in ''{0}''", TO_STRING);
MAP.put(USAGE_IS_NOT_INLINABLE, "Illegal usage of inline-parameter ''{0}'' in ''{1}''. Annotate the parameter with [noinline]", ELEMENT_TEXT, TO_STRING);
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, TO_STRING);
MAP.setImmutable();
for (Field field : Errors.class.getFields()) {
@@ -20,9 +20,10 @@ import org.jetbrains.annotations.NotNull;
import org.jetbrains.jet.lang.descriptors.FunctionDescriptor;
import org.jetbrains.jet.lang.descriptors.SimpleFunctionDescriptor;
import org.jetbrains.jet.lang.psi.JetNamedFunction;
import org.jetbrains.jet.lang.resolve.extension.InlineAnalyzerExtension;
import javax.inject.Inject;
import java.util.Collections;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;
@@ -36,7 +37,7 @@ public class FunctionAnalyzerExtension {
private BindingTrace trace;
@Inject
public void setTrace(BindingTrace trace) {
public void setTrace(@NotNull BindingTrace trace) {
this.trace = trace;
}
@@ -52,8 +53,13 @@ public class FunctionAnalyzerExtension {
}
@NotNull
private List<AnalyzerExtension> getExtensions(@NotNull FunctionDescriptor functionDescriptor) {
return Collections.emptyList();
private static List<AnalyzerExtension> getExtensions(@NotNull FunctionDescriptor functionDescriptor) {
List<AnalyzerExtension> list = new ArrayList<AnalyzerExtension>();
if (functionDescriptor instanceof SimpleFunctionDescriptor &&
((SimpleFunctionDescriptor) functionDescriptor).isInline()) {
list.add(InlineAnalyzerExtension.INSTANCE);
}
return list;
}
}
@@ -19,6 +19,7 @@ package org.jetbrains.jet.lang.resolve.calls;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
import org.jetbrains.jet.lang.descriptors.DeclarationDescriptor;
import org.jetbrains.jet.lang.descriptors.SimpleFunctionDescriptor;
import java.lang.ref.WeakReference;
import java.util.*;
@@ -69,8 +70,13 @@ public class CallResolverExtensionProvider {
}
// with default one at the end
private void appendExtensionsFor(DeclarationDescriptor declarationDescriptor, List<CallResolverExtension> extensions) {
// add your extensions here
private static void appendExtensionsFor(DeclarationDescriptor declarationDescriptor, List<CallResolverExtension> extensions) {
if (declarationDescriptor instanceof SimpleFunctionDescriptor) {
SimpleFunctionDescriptor descriptor = (SimpleFunctionDescriptor) declarationDescriptor;
if (descriptor.isInline()) {
extensions.add(new InlineCallResolverExtension(descriptor));
}
}
extensions.add(DEFAULT);
}
}
@@ -0,0 +1,189 @@
/*
* Copyright 2010-2013 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.jet.lang.resolve.calls;
import com.intellij.psi.PsiElement;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
import org.jetbrains.jet.lang.descriptors.*;
import org.jetbrains.jet.lang.diagnostics.Errors;
import org.jetbrains.jet.lang.psi.*;
import org.jetbrains.jet.lang.resolve.BindingContext;
import org.jetbrains.jet.lang.resolve.calls.context.BasicCallResolutionContext;
import org.jetbrains.jet.lang.resolve.calls.model.ExpressionValueArgument;
import org.jetbrains.jet.lang.resolve.calls.model.ResolvedCall;
import org.jetbrains.jet.lang.resolve.calls.model.ResolvedValueArgument;
import org.jetbrains.jet.lang.resolve.scopes.receivers.ExpressionReceiver;
import org.jetbrains.jet.lang.resolve.scopes.receivers.ExtensionReceiver;
import org.jetbrains.jet.lang.resolve.scopes.receivers.ReceiverValue;
import org.jetbrains.jet.lang.types.JetType;
import org.jetbrains.jet.lang.types.lang.InlineUtil;
import org.jetbrains.jet.lang.types.lang.KotlinBuiltIns;
import java.util.*;
public class InlineCallResolverExtension implements CallResolverExtension {
private SimpleFunctionDescriptor descriptor;
private Set<DeclarationDescriptor> inlinableParameters = new HashSet<DeclarationDescriptor>();
public InlineCallResolverExtension(@NotNull SimpleFunctionDescriptor descriptor) {
assert descriptor.isInline() : "This extension should be created only for inline functions but not " + descriptor;
this.descriptor = descriptor;
Iterator<ValueParameterDescriptor> iterator = descriptor.getValueParameters().iterator();
while (iterator.hasNext()) {
ValueParameterDescriptor next = iterator.next();
JetType type = next.getType();
if (KotlinBuiltIns.getInstance().isExactFunctionOrExtensionFunctionType(type)) {
//TODO check annotations
if (!InlineUtil.hasNoinlineAnnotation(next)) {
inlinableParameters.add(next);
}
}
}
//add extension receiver as inlineable
ReceiverParameterDescriptor receiverParameter = descriptor.getReceiverParameter();
if (receiverParameter != null) {
if (isExactFunctionOrExtensionFunctionType(receiverParameter.getType())) {
inlinableParameters.add(receiverParameter);
}
}
}
@Override
public <F extends CallableDescriptor> void run(
@NotNull ResolvedCall<F> resolvedCall, @NotNull BasicCallResolutionContext context
) {
CallableDescriptor targetDescriptor = resolvedCall.getResultingDescriptor();
JetExpression expression = context.call.getCalleeExpression();
if (expression == null) {
return;
}
//checking that only invoke or inlinable extension called on function parameter
checkCallWithReceiver(context, targetDescriptor, resolvedCall.getThisObject(), expression);
checkCallWithReceiver(context, targetDescriptor, resolvedCall.getReceiverArgument(), expression);
boolean isInlinableClosure = inlinableParameters.contains(targetDescriptor);
if (isInlinableClosure) {
PsiElement parent = expression.getParent();
if (parent instanceof JetValueArgument || parent instanceof JetBinaryExpression || parent instanceof JetDotQualifiedExpression || parent instanceof JetCallExpression) {
//check that it's in inlineable call would be in resolve call of parent
} else {
context.trace.report(Errors.USAGE_IS_NOT_INLINABLE.on(expression, expression, descriptor));
}
}
for (Map.Entry<ValueParameterDescriptor, ResolvedValueArgument> entry : resolvedCall.getValueArguments().entrySet()) {
ResolvedValueArgument value = entry.getValue();
if (value instanceof ExpressionValueArgument) {
JetExpression jetExpression = ((ExpressionValueArgument) value).getValueArgument().getArgumentExpression();
DeclarationDescriptor varDescriptor = getDescriptor(context, jetExpression);
if (varDescriptor != null && inlinableParameters.contains(varDescriptor)) {
checkFunctionCall(context, targetDescriptor, jetExpression);
}
}
//TODO default and vararg
}
}
private void checkCallWithReceiver(
@NotNull BasicCallResolutionContext context,
@NotNull CallableDescriptor targetDescriptor,
@NotNull ReceiverValue receiver,
@Nullable JetExpression expression
) {
if (receiver.exists()) {
CallableDescriptor varDescriptor = null;
JetExpression receiverExpression = null;
if (receiver instanceof ExpressionReceiver) {
receiverExpression = ((ExpressionReceiver) receiver).getExpression();
varDescriptor = getDescriptor(context, receiverExpression);
}
else if (receiver instanceof ExtensionReceiver) {
ExtensionReceiver extensionReceiver = (ExtensionReceiver) receiver;
CallableDescriptor extensionFunction = extensionReceiver.getDeclarationDescriptor();
ReceiverParameterDescriptor receiverParameter = extensionFunction.getReceiverParameter();
assert receiverParameter != null : "Extension function should have receiverParameterDescriptor: " + extensionFunction;
varDescriptor = receiverParameter;
receiverExpression = expression;
}
if (varDescriptor != null) {
if (inlinableParameters.contains(varDescriptor)) {
//check that it's invoke
checkFunctionCall(context, targetDescriptor, receiverExpression);
}
}
}
}
@Nullable
private static CallableDescriptor getDescriptor(
@NotNull BasicCallResolutionContext context,
@NotNull JetExpression expression
) {
ResolvedCall<? extends CallableDescriptor> thisCall = context.trace.get(BindingContext.RESOLVED_CALL, expression);
return thisCall != null ? thisCall.getResultingDescriptor() : null;
}
private void checkFunctionCall(
BasicCallResolutionContext context,
CallableDescriptor targetDescriptor,
JetExpression receiverExpresssion
) {
if (!isInvokeOrInlineExtension(targetDescriptor)) {
context.trace.report(Errors.USAGE_IS_NOT_INLINABLE.on(receiverExpresssion, receiverExpresssion, descriptor));
}
}
private boolean isExactFunctionOrExtensionFunctionType(@NotNull JetType type) {
return KotlinBuiltIns.getInstance().isExactFunctionOrExtensionFunctionType(type);
}
private static boolean isInvokeOrInlineExtension(@NotNull CallableDescriptor descriptor) {
if (!(descriptor instanceof SimpleFunctionDescriptor)) {
return false;
}
DeclarationDescriptor containingDeclaration = descriptor.getContainingDeclaration();
boolean isInvoke = descriptor.getName().asString().equals("invoke") &&
containingDeclaration instanceof ClassDescriptor &&
isExactFunctionOrExtensionFunctionType(((ClassDescriptor) containingDeclaration).getDefaultType());
return isInvoke ||
//or inline extension
((SimpleFunctionDescriptor) descriptor).isInline();
}
private void checkVisibility(){
}
interface FunctionParameter {
}
}
@@ -0,0 +1,65 @@
/*
* Copyright 2010-2013 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.jet.lang.resolve.extension;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.jet.lang.descriptors.FunctionDescriptor;
import org.jetbrains.jet.lang.diagnostics.Errors;
import org.jetbrains.jet.lang.psi.*;
import org.jetbrains.jet.lang.resolve.BindingTrace;
import org.jetbrains.jet.lang.resolve.FunctionAnalyzerExtension;
public class InlineAnalyzerExtension implements FunctionAnalyzerExtension.AnalyzerExtension {
public static final InlineAnalyzerExtension INSTANCE = new InlineAnalyzerExtension();
private InlineAnalyzerExtension() {
}
@Override
public void process(
@NotNull final FunctionDescriptor descriptor, @NotNull JetNamedFunction function, @NotNull final BindingTrace trace
) {
JetVisitorVoid visitor = new JetVisitorVoid() {
@Override
public void visitJetElement(@NotNull JetElement element) {
super.visitJetElement(element);
element.acceptChildren(this);
}
@Override
public void visitClass(@NotNull JetClass klass) {
trace.report(Errors.NOT_YET_SUPPORTED_IN_INLINE.on(klass, klass, descriptor));
}
@Override
public void visitObjectDeclaration(@NotNull JetObjectDeclaration declaration) {
trace.report(Errors.NOT_YET_SUPPORTED_IN_INLINE.on(declaration, declaration, descriptor));
}
@Override
public void visitNamedFunction(@NotNull JetNamedFunction function) {
trace.report(Errors.NOT_YET_SUPPORTED_IN_INLINE.on(function, function, descriptor));
}
};
function.acceptChildren(visitor);
}
}
@@ -0,0 +1,51 @@
// !DIAGNOSTICS: -UNUSED_EXPRESSION -UNUSED_PARAMETER -UNUSED_VARIABLE
fun Function1<Int, Unit>.noInlineExt(p: Int) {}
inline fun Function1<Int, Unit>.inlineExt2(p: Int) {
{
<!USAGE_IS_NOT_INLINABLE!>noInlineExt<!>(11)
<!USAGE_IS_NOT_INLINABLE!>this<!>.noInlineExt(11)
<!USAGE_IS_NOT_INLINABLE!>this<!> noInlineExt 11
<!USAGE_IS_NOT_INLINABLE!>this<!>
}()
}
inline fun Function1<Int, Unit>.inlineExt() {
{
inlineExt2(1)
this.inlineExt2(1)
this inlineExt2 1
this(11)
}()
}
inline fun inlineFunWithInvoke(s: (p: Int) -> Unit) {
{
s(11)
s.invoke(11)
s invoke 11
}()
}
inline fun inlineFunWithInvokeNonInline(noinline s: (p: Int) -> Unit) {
{
s(11)
s.invoke(11)
s invoke 11
}()
}
inline fun testExtension(s: (p: Int) -> Unit) {
{
s.inlineExt()
} ()
}
inline fun inlineFunWrongExtension(s: (p: Int) -> Unit) {
{
<!USAGE_IS_NOT_INLINABLE!>s<!>.noInlineExt(11)
} ()
}
@@ -0,0 +1,7 @@
class Z(s: (Int) -> Int) {
}
public inline fun test(s : (Int) -> Int) {
<!INVISIBLE_MEMBER_FROM_INLINE!>Z<!>(<!USAGE_IS_NOT_INLINABLE!>s<!>)
}
@@ -0,0 +1,28 @@
// !DIAGNOSTICS: -UNUSED_EXPRESSION -UNUSED_PARAMETER -UNUSED_VARIABLE
fun Function1<Int, Unit>.noInlineExt(p: Int) {}
inline fun Function1<Int, Unit>.inlineExt2(p: Int) {
<!USAGE_IS_NOT_INLINABLE!>noInlineExt<!>(11)
<!USAGE_IS_NOT_INLINABLE!>this<!>.noInlineExt(11)
<!USAGE_IS_NOT_INLINABLE!>this<!> noInlineExt 11
<!USAGE_IS_NOT_INLINABLE!>this<!>
}
inline fun Function1<Int, Unit>.inlineExt() {
inlineExt2(1)
this.inlineExt2(1)
this inlineExt2 1
}
inline fun testExtension(s: (p: Int) -> Unit) {
s.inlineExt()
}
inline fun inlineFunWrongExtension(s: (p: Int) -> Unit) {
<!USAGE_IS_NOT_INLINABLE!>s<!>.noInlineExt(11)
}
inline fun inlineFunNoInline(noinline s: (p: Int) -> Unit) {
s.noInlineExt(11)
}
@@ -0,0 +1,12 @@
// !DIAGNOSTICS: -UNUSED_EXPRESSION -UNUSED_PARAMETER -UNUSED_VARIABLE -UNNECESSARY_NOT_NULL_ASSERTION -UNNECESSARY_SAFE_CALL
fun getFun(s: (p: Int) -> Unit): Function1<Int, Int> = {11}
inline fun getInlineFun(s: (p: Int) -> Unit): Function1<Int, Int> = {11}
inline fun testExtension(s: (p: Int) -> Unit) {
getFun(<!USAGE_IS_NOT_INLINABLE!>s<!>).invoke(10)
getInlineFun(s).invoke(10)
getInlineFun(s)!!.invoke(10)
getInlineFun(s)?.invoke(10)
}
@@ -0,0 +1,26 @@
// !DIAGNOSTICS: -UNUSED_EXPRESSION -UNUSED_PARAMETER -UNUSED_VARIABLE
inline fun inlineFunWithInvoke(s: (p: Int) -> Unit, ext: Int.(p: Int) -> Unit) {
s(11)
s.invoke(11)
s invoke 11
11.ext(11)
11 ext 11
}
inline fun inlineFunWithInvokeNonInline(noinline s: (p: Int) -> Unit, ext: Int.(p: Int) -> Unit) {
s(11)
s.invoke(11)
s invoke 11
11.ext(11)
11 ext 11
}
inline fun Function1<Int, Unit>.inlineExt() {
invoke(11)
this.invoke(11)
this invoke 11
this(11)
}
@@ -0,0 +1,37 @@
// !DIAGNOSTICS: -UNUSED_EXPRESSION -UNUSED_PARAMETER -UNUSED_VARIABLE
inline fun inlineFunWithInvoke(s: (p: Int) -> Unit, ext: Int.(p: Int) -> Unit) {
subInline(s, ext)
subNoInline(<!USAGE_IS_NOT_INLINABLE!>s<!>, <!USAGE_IS_NOT_INLINABLE!>ext<!>)
}
inline fun inlineFunWithInvokeClosure(s: (p: Int) -> Unit, ext: Int.(p: Int) -> Unit) {
subInline({(p: Int) -> s(p)}, {Int.(p:Int) -> this.ext(p)})
subNoInline({(p: Int) -> s(p)}, {Int.(p:Int) -> this.ext(p)})
}
//No inline
inline fun inlineFunWithInvokeNonInline(noinline s: (p: Int) -> Unit, noinline ext: Int.(p: Int) -> Unit) {
subInline(s, ext)
subNoInline(s, ext)
}
inline fun inlineFunWithInvokeClosureNoinline(noinline s: (p: Int) -> Unit, noinline ext: Int.(p: Int) -> Unit) {
subInline({(p: Int) -> s(p)}, {Int.(p:Int) -> this.ext(p)})
subNoInline({(p: Int) -> s(p)}, {Int.(p:Int) -> this.ext(p)})
}
//ext function
inline fun Function1<Int, Unit>.inlineExt(ext: Int.(p: Int) -> Unit) {
subInline(this, ext)
subNoInline(<!USAGE_IS_NOT_INLINABLE!>this<!>, <!USAGE_IS_NOT_INLINABLE!>ext<!>)
}
inline fun Function1<Int, Unit>.inlineExtWithClosure(ext: Int.(p: Int) -> Unit) {
subInline({(p: Int) -> this(p)}, {Int.(p:Int) -> this.ext(p)})
subNoInline({(p: Int) -> this(p)}, {Int.(p:Int) -> this.ext(p)})
}
inline fun subInline(s: (p: Int) -> Unit, ext: Int.(p: Int) -> Unit) {}
fun subNoInline(s: (p: Int) -> Unit, ext: Int.(p: Int) -> Unit) {}
@@ -0,0 +1,20 @@
inline fun inlineFun(s: (p: Int) -> Unit) : (p: Int) -> Unit {
return <!USAGE_IS_NOT_INLINABLE!>s<!>
}
inline fun inlineFun2(s: (p: Int) -> Unit) : (p: Int) -> Unit = <!USAGE_IS_NOT_INLINABLE!>s<!>
inline fun inlineFunWithExt(ext: Int.(p: Int) -> Unit) : Int.(p: Int) -> Unit {
return <!USAGE_IS_NOT_INLINABLE!>ext<!>
}
inline fun inlineFunWithExt2(ext: Int.(p: Int) -> Unit) : Int.(p: Int) -> Unit = <!USAGE_IS_NOT_INLINABLE!>ext<!>
inline fun Function1<Int, Unit>.inlineExt(): Function1<Int, Unit> {
return <!USAGE_IS_NOT_INLINABLE!>this<!>
}
inline fun Function1<Int, Unit>.inlineExt2(): Function1<Int, Unit> = <!USAGE_IS_NOT_INLINABLE!>this<!>
@@ -0,0 +1,26 @@
// !DIAGNOSTICS: -UNUSED_EXPRESSION -UNUSED_PARAMETER -UNUSED_VARIABLE
inline fun unsupported() {
<!NOT_YET_SUPPORTED_IN_INLINE!>class A {
fun a() {
class AInner {}
}
}<!>
<!NOT_YET_SUPPORTED_IN_INLINE!>object B{
object BInner {}
}<!>
val s = <!NOT_YET_SUPPORTED_IN_INLINE!>object {
fun a() {
val sInner = object {
fun aInner() {}
}
}
}<!>
<!NOT_YET_SUPPORTED_IN_INLINE!>fun local() {
fun localInner() {}
}<!>
}
@@ -0,0 +1,55 @@
// !DIAGNOSTICS: -UNUSED_EXPRESSION -UNUSED_PARAMETER -UNUSED_VARIABLE -ASSIGNED_BUT_NEVER_ACCESSED_VARIABLE -UNUSED_VALUE
inline fun inlineFunWrongUsage(s: (p: Int) -> Unit) {
<!USAGE_IS_NOT_INLINABLE!>s<!>
if (true) <!USAGE_IS_NOT_INLINABLE!>s<!> else 0
var c = <!USAGE_IS_NOT_INLINABLE!>s<!>
c = <!USAGE_IS_NOT_INLINABLE!>s<!>
}
inline fun inlineFunWrongUsageExt(ext: Int.(p: Int) -> Unit) {
<!USAGE_IS_NOT_INLINABLE!>ext<!>
if (true) <!USAGE_IS_NOT_INLINABLE!>ext<!> else 0
var c = <!USAGE_IS_NOT_INLINABLE!>ext<!>
c = <!USAGE_IS_NOT_INLINABLE!>ext<!>
}
inline fun inlineFunWrongUsageInClosure(s: (p: Int) -> Unit) {
{
<!USAGE_IS_NOT_INLINABLE!>s<!>
if (true) <!USAGE_IS_NOT_INLINABLE!>s<!> else 0
var c = <!USAGE_IS_NOT_INLINABLE!>s<!>
c = <!USAGE_IS_NOT_INLINABLE!>s<!>
}()
}
inline fun inlineFunWrongUsageInClosureExt(ext: Int.(p: Int) -> Unit) {
{
<!USAGE_IS_NOT_INLINABLE!>ext<!>
if (true) <!USAGE_IS_NOT_INLINABLE!>ext<!> else 0
var c = <!USAGE_IS_NOT_INLINABLE!>ext<!>
c = <!USAGE_IS_NOT_INLINABLE!>ext<!>
}()
}
inline fun inlineFunNoInline(noinline s: (p: Int) -> Unit) {
s
if (true) s else 0
var c = s
c = s
}
inline fun inlineFunNoInline(noinline ext: Int.(p: Int) -> Unit) {
ext
if (true) ext else 0
var c = ext
c = ext
}
@@ -0,0 +1,24 @@
// !DIAGNOSTICS: -UNUSED_EXPRESSION -UNUSED_PARAMETER -UNUSED_VARIABLE -UNNECESSARY_SAFE_CALL -UNNECESSARY_NOT_NULL_ASSERTION
public inline fun assertNot(message: String, block: ()-> Boolean) {}
public inline fun assertNot(block: ()-> Boolean) : Unit = assertNot(<!USAGE_IS_NOT_INLINABLE!>block<!>.toString(), block)
public fun <T> callable(action: ()-> T) {
}
public inline fun <T> String.submit(action: ()->T) {
callable(<!USAGE_IS_NOT_INLINABLE!>action<!>)
}
public inline fun <T> Function1<Int, Int>.submit() {
<!USAGE_IS_NOT_INLINABLE!>this<!>?.invoke(11)
<!USAGE_IS_NOT_INLINABLE, USAGE_IS_NOT_INLINABLE!>this<!>!!.invoke(11)
}
public inline fun <T> submit(action: Function1<Int, Int>) {
<!USAGE_IS_NOT_INLINABLE!>action<!>?.invoke(10)
<!USAGE_IS_NOT_INLINABLE, USAGE_IS_NOT_INLINABLE!>action<!>!!.invoke(10)
}
@@ -33,7 +33,7 @@ import org.jetbrains.jet.checkers.AbstractDiagnosticsTestWithEagerResolve;
@InnerTestClasses({JetDiagnosticsTestGenerated.Tests.class, JetDiagnosticsTestGenerated.Script.class})
public class JetDiagnosticsTestGenerated extends AbstractDiagnosticsTestWithEagerResolve {
@TestMetadata("compiler/testData/diagnostics/tests")
@InnerTestClasses({Tests.Annotations.class, Tests.BackingField.class, Tests.CallableReference.class, Tests.Cast.class, Tests.CheckArguments.class, Tests.ClassObjects.class, Tests.ControlFlowAnalysis.class, Tests.ControlStructures.class, Tests.DataClasses.class, Tests.DataFlow.class, Tests.DataFlowInfoTraversal.class, Tests.DeclarationChecks.class, Tests.DelegatedProperty.class, Tests.Deparenthesize.class, Tests.Enum.class, Tests.Extensions.class, Tests.FunctionLiterals.class, Tests.Generics.class, Tests.IncompleteCode.class, Tests.Inference.class, Tests.Infos.class, Tests.Inner.class, Tests.J_k.class, Tests.Jdk_annotations.class, Tests.Library.class, Tests.NullabilityAndAutoCasts.class, Tests.NullableTypes.class, Tests.Numbers.class, Tests.Objects.class, Tests.OperatorsOverloading.class, Tests.Overload.class, Tests.Override.class, Tests.Recovery.class, Tests.Redeclarations.class, Tests.Regressions.class, Tests.Resolve.class, Tests.Scopes.class, Tests.SenselessComparison.class, Tests.Shadowing.class, Tests.SmartCasts.class, Tests.Substitutions.class, Tests.Subtyping.class, Tests.Suppress.class, Tests.ThisAndSuper.class, Tests.Varargs.class, Tests.When.class})
@InnerTestClasses({Tests.Annotations.class, Tests.BackingField.class, Tests.CallableReference.class, Tests.Cast.class, Tests.CheckArguments.class, Tests.ClassObjects.class, Tests.ControlFlowAnalysis.class, Tests.ControlStructures.class, Tests.DataClasses.class, Tests.DataFlow.class, Tests.DataFlowInfoTraversal.class, Tests.DeclarationChecks.class, Tests.DelegatedProperty.class, Tests.Deparenthesize.class, Tests.Enum.class, Tests.Extensions.class, Tests.FunctionLiterals.class, Tests.Generics.class, Tests.IncompleteCode.class, Tests.Inference.class, Tests.Infos.class, Tests.Inline.class, Tests.Inner.class, Tests.J_k.class, Tests.Jdk_annotations.class, Tests.Library.class, Tests.NullabilityAndAutoCasts.class, Tests.NullableTypes.class, Tests.Numbers.class, Tests.Objects.class, Tests.OperatorsOverloading.class, Tests.Overload.class, Tests.Override.class, Tests.Recovery.class, Tests.Redeclarations.class, Tests.Regressions.class, Tests.Resolve.class, Tests.Scopes.class, Tests.SenselessComparison.class, Tests.Shadowing.class, Tests.SmartCasts.class, Tests.Substitutions.class, Tests.Subtyping.class, Tests.Suppress.class, Tests.ThisAndSuper.class, Tests.Varargs.class, Tests.When.class})
public static class Tests extends AbstractDiagnosticsTestWithEagerResolve {
@TestMetadata("Abstract.kt")
public void testAbstract() throws Exception {
@@ -3750,6 +3750,64 @@ public class JetDiagnosticsTestGenerated extends AbstractDiagnosticsTestWithEage
}
@TestMetadata("compiler/testData/diagnostics/tests/inline")
public static class Inline extends AbstractDiagnosticsTestWithEagerResolve {
public void testAllFilesPresentInInline() throws Exception {
JetTestUtils.assertAllTestsPresentByMetadata(this.getClass(), "org.jetbrains.jet.generators.tests.GenerateTests", new File("compiler/testData/diagnostics/tests/inline"), Pattern.compile("^(.+)\\.kt$"), true);
}
@TestMetadata("capture.kt")
public void testCapture() throws Exception {
doTest("compiler/testData/diagnostics/tests/inline/capture.kt");
}
@TestMetadata("constructor.kt")
public void testConstructor() throws Exception {
doTest("compiler/testData/diagnostics/tests/inline/constructor.kt");
}
@TestMetadata("extensionOnFunction.kt")
public void testExtensionOnFunction() throws Exception {
doTest("compiler/testData/diagnostics/tests/inline/extensionOnFunction.kt");
}
@TestMetadata("functions.kt")
public void testFunctions() throws Exception {
doTest("compiler/testData/diagnostics/tests/inline/functions.kt");
}
@TestMetadata("invoke.kt")
public void testInvoke() throws Exception {
doTest("compiler/testData/diagnostics/tests/inline/invoke.kt");
}
@TestMetadata("propagation.kt")
public void testPropagation() throws Exception {
doTest("compiler/testData/diagnostics/tests/inline/propagation.kt");
}
@TestMetadata("returns.kt")
public void testReturns() throws Exception {
doTest("compiler/testData/diagnostics/tests/inline/returns.kt");
}
@TestMetadata("unsupportedConstruction.kt")
public void testUnsupportedConstruction() throws Exception {
doTest("compiler/testData/diagnostics/tests/inline/unsupportedConstruction.kt");
}
@TestMetadata("wrongUsage.kt")
public void testWrongUsage() throws Exception {
doTest("compiler/testData/diagnostics/tests/inline/wrongUsage.kt");
}
@TestMetadata("wrongUsage2.kt")
public void testWrongUsage2() throws Exception {
doTest("compiler/testData/diagnostics/tests/inline/wrongUsage2.kt");
}
}
@TestMetadata("compiler/testData/diagnostics/tests/inner")
@InnerTestClasses({Inner.QualifiedExpression.class})
public static class Inner extends AbstractDiagnosticsTestWithEagerResolve {
@@ -6255,6 +6313,7 @@ public class JetDiagnosticsTestGenerated extends AbstractDiagnosticsTestWithEage
suite.addTest(IncompleteCode.innerSuite());
suite.addTest(Inference.innerSuite());
suite.addTestSuite(Infos.class);
suite.addTestSuite(Inline.class);
suite.addTest(Inner.innerSuite());
suite.addTestSuite(J_k.class);
suite.addTest(Jdk_annotations.innerSuite());
@@ -32,7 +32,7 @@ public class ExtensionReceiver extends AbstractReceiverValue implements ThisRece
@NotNull
@Override
public DeclarationDescriptor getDeclarationDescriptor() {
public CallableDescriptor getDeclarationDescriptor() {
return descriptor;
}