diff --git a/compiler/frontend/src/org/jetbrains/jet/lang/resolve/calls/CallResolver.java b/compiler/frontend/src/org/jetbrains/jet/lang/resolve/calls/CallResolver.java index cb2850ae44d..e7ac84606a9 100644 --- a/compiler/frontend/src/org/jetbrains/jet/lang/resolve/calls/CallResolver.java +++ b/compiler/frontend/src/org/jetbrains/jet/lang/resolve/calls/CallResolver.java @@ -39,6 +39,7 @@ import org.jetbrains.jet.lang.resolve.scopes.receivers.ReceiverDescriptor; import org.jetbrains.jet.lang.types.*; import org.jetbrains.jet.lang.types.checker.JetTypeChecker; import org.jetbrains.jet.lang.types.expressions.ExpressionTypingServices; +import org.jetbrains.jet.lang.types.expressions.ExpressionTypingUtils; import org.jetbrains.jet.lang.types.lang.JetStandardClasses; import org.jetbrains.jet.lexer.JetTokens; import org.jetbrains.jet.util.slicedmap.WritableSlice; @@ -149,6 +150,8 @@ public class CallResolver { JetSimpleNameExpression expression = (JetSimpleNameExpression) calleeExpression; functionReference = expression; + ExpressionTypingUtils.checkWrappingInRef(expression, context.trace, context.scope); + Name name = expression.getReferencedNameAsName(); if (name == null) return checkArgumentTypesAndFail(context); diff --git a/compiler/frontend/src/org/jetbrains/jet/lang/types/expressions/BasicExpressionTypingVisitor.java b/compiler/frontend/src/org/jetbrains/jet/lang/types/expressions/BasicExpressionTypingVisitor.java index 65bc1a11294..b83a8faa5a4 100644 --- a/compiler/frontend/src/org/jetbrains/jet/lang/types/expressions/BasicExpressionTypingVisitor.java +++ b/compiler/frontend/src/org/jetbrains/jet/lang/types/expressions/BasicExpressionTypingVisitor.java @@ -73,7 +73,7 @@ public class BasicExpressionTypingVisitor extends ExpressionTypingVisitor { // TODO : type substitutions??? JetTypeInfo typeInfo = getSelectorReturnTypeInfo(NO_RECEIVER, null, expression, context); JetType type = DataFlowUtils.checkType(typeInfo.getType(), expression, context); - ExpressionTypingUtils.checkWrappingInRef(expression, context); + ExpressionTypingUtils.checkWrappingInRef(expression, context.trace, context.scope); return JetTypeInfo.create(type, typeInfo.getDataFlowInfo()); // TODO : Extensions to this } diff --git a/compiler/frontend/src/org/jetbrains/jet/lang/types/expressions/ExpressionTypingUtils.java b/compiler/frontend/src/org/jetbrains/jet/lang/types/expressions/ExpressionTypingUtils.java index c03e85dcc92..26855ed2767 100644 --- a/compiler/frontend/src/org/jetbrains/jet/lang/types/expressions/ExpressionTypingUtils.java +++ b/compiler/frontend/src/org/jetbrains/jet/lang/types/expressions/ExpressionTypingUtils.java @@ -137,12 +137,12 @@ public class ExpressionTypingUtils { ).contains(expression.getNode().getElementType()); } - public static void checkWrappingInRef(JetSimpleNameExpression expression, ExpressionTypingContext context) { - VariableDescriptor variable = BindingContextUtils.extractVariableDescriptorIfAny(context.trace.getBindingContext(), expression, true); + public static void checkWrappingInRef(JetSimpleNameExpression expression, BindingTrace trace, JetScope scope) { + VariableDescriptor variable = BindingContextUtils.extractVariableDescriptorIfAny(trace.getBindingContext(), expression, true); if (variable != null) { DeclarationDescriptor containingDeclaration = variable.getContainingDeclaration(); - if (context.scope.getContainingDeclaration() != containingDeclaration && containingDeclaration instanceof CallableDescriptor) { - context.trace.record(CAPTURED_IN_CLOSURE, variable); + if (scope.getContainingDeclaration() != containingDeclaration && containingDeclaration instanceof CallableDescriptor) { + trace.record(CAPTURED_IN_CLOSURE, variable); } } } diff --git a/compiler/testData/diagnostics/tests/functionLiterals/kt2906.kt b/compiler/testData/diagnostics/tests/functionLiterals/kt2906.kt new file mode 100644 index 00000000000..0e19662bf89 --- /dev/null +++ b/compiler/testData/diagnostics/tests/functionLiterals/kt2906.kt @@ -0,0 +1,23 @@ +//KT-2906 If function parameter/variable is invoked in closure using parenthesis syntax, in IDEA it is not highlighted as captured in closure + +package bug + +public fun foo1(bar: () -> Unit) { + run { + bar() // ERROR: not highlighted as "captured in closure" + } +} + +public fun foo2(bar: () -> Unit) { + run { + bar.invoke() // CORRECT: highlighted as "captured in closure" + } +} + +fun main(args: Array) { + foo1 { println ("foo1")} // prints "foo1" + foo2 { println ("foo2")} // prints "foo2" +} + +fun run(f: () -> T) : T = f() +fun println(s: String) = s diff --git a/compiler/tests/org/jetbrains/jet/checkers/JetDiagnosticsTestGenerated.java b/compiler/tests/org/jetbrains/jet/checkers/JetDiagnosticsTestGenerated.java index f91af9c00ef..33ba5f88744 100644 --- a/compiler/tests/org/jetbrains/jet/checkers/JetDiagnosticsTestGenerated.java +++ b/compiler/tests/org/jetbrains/jet/checkers/JetDiagnosticsTestGenerated.java @@ -30,7 +30,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.Cast.class, Tests.CheckArguments.class, Tests.ControlFlowAnalysis.class, Tests.ControlStructures.class, Tests.DataClasses.class, Tests.DataFlow.class, Tests.DataFlowInfoTraversal.class, Tests.DeclarationChecks.class, Tests.Enum.class, Tests.Extensions.class, Tests.Generics.class, Tests.IncompleteCode.class, Tests.Inference.class, Tests.Infos.class, Tests.J_k.class, Tests.Jdk_annotations.class, Tests.Library.class, Tests.NullabilityAndAutoCasts.class, Tests.Objects.class, Tests.OperatorsOverloading.class, Tests.Overload.class, Tests.Override.class, Tests.Redeclarations.class, Tests.Regressions.class, Tests.Scopes.class, Tests.Shadowing.class, Tests.Substitutions.class, Tests.Subtyping.class, Tests.Tuples.class, Tests.Varargs.class}) + @InnerTestClasses({Tests.Annotations.class, Tests.BackingField.class, Tests.Cast.class, Tests.CheckArguments.class, Tests.ControlFlowAnalysis.class, Tests.ControlStructures.class, Tests.DataClasses.class, Tests.DataFlow.class, Tests.DataFlowInfoTraversal.class, Tests.DeclarationChecks.class, Tests.Enum.class, Tests.Extensions.class, Tests.FunctionLiterals.class, Tests.Generics.class, Tests.IncompleteCode.class, Tests.Inference.class, Tests.Infos.class, Tests.J_k.class, Tests.Jdk_annotations.class, Tests.Library.class, Tests.NullabilityAndAutoCasts.class, Tests.Objects.class, Tests.OperatorsOverloading.class, Tests.Overload.class, Tests.Override.class, Tests.Redeclarations.class, Tests.Regressions.class, Tests.Scopes.class, Tests.Shadowing.class, Tests.Substitutions.class, Tests.Subtyping.class, Tests.Tuples.class, Tests.Varargs.class}) public static class Tests extends AbstractDiagnosticsTestWithEagerResolve { @TestMetadata("Abstract.kt") public void testAbstract() throws Exception { @@ -1542,6 +1542,19 @@ public class JetDiagnosticsTestGenerated extends AbstractDiagnosticsTestWithEage } + @TestMetadata("compiler/testData/diagnostics/tests/functionLiterals") + public static class FunctionLiterals extends AbstractDiagnosticsTestWithEagerResolve { + public void testAllFilesPresentInFunctionLiterals() throws Exception { + JetTestUtils.assertAllTestsPresentByMetadata(this.getClass(), "org.jetbrains.jet.checkers.AbstractDiagnosticsTestWithEagerResolve", new File("compiler/testData/diagnostics/tests/functionLiterals"), "kt", true); + } + + @TestMetadata("kt2906.kt") + public void testKt2906() throws Exception { + doTest("compiler/testData/diagnostics/tests/functionLiterals/kt2906.kt"); + } + + } + @TestMetadata("compiler/testData/diagnostics/tests/generics") public static class Generics extends AbstractDiagnosticsTestWithEagerResolve { public void testAllFilesPresentInGenerics() throws Exception { @@ -3496,6 +3509,7 @@ public class JetDiagnosticsTestGenerated extends AbstractDiagnosticsTestWithEage suite.addTest(DeclarationChecks.innerSuite()); suite.addTest(Enum.innerSuite()); suite.addTestSuite(Extensions.class); + suite.addTestSuite(FunctionLiterals.class); suite.addTestSuite(Generics.class); suite.addTest(IncompleteCode.innerSuite()); suite.addTest(Inference.innerSuite());