From 49f063522c1a52418bbb5e594e5f5d94aa5dbc78 Mon Sep 17 00:00:00 2001 From: Michael Bogdanov Date: Tue, 28 Apr 2015 17:28:55 +0300 Subject: [PATCH] Inline util functions renaming --- .../kotlin/codegen/ClosureCodegen.java | 2 +- .../kotlin/codegen/ExpressionCodegen.java | 2 +- .../kotlin/codegen/JvmCodegenUtil.java | 6 ++--- .../codegen/binding/CodegenBinding.java | 2 +- .../kotlin/codegen/inline/InlineCodegen.java | 2 -- .../checkers/CapturingInClosureChecker.kt | 4 +-- .../kotlin/resolve/inline/InlineUtil.java | 20 +++++++------- .../idea/codeInsight/CodeInsightUtils.java | 26 ++++++++++--------- .../idea/debugger/JetPositionManager.kt | 22 +++++++--------- ...KotlinHighlightExitPointsHandlerFactory.kt | 5 ++-- .../KotlinRecursiveCallLineMarkerProvider.kt | 4 +-- .../inInlinedFunctionExpression.kt | 4 ++- .../{functionalExpression.kt => localFun.kt} | 2 +- .../codeInsight/LineMarkersTestGenerated.java | 12 ++++----- 14 files changed, 55 insertions(+), 58 deletions(-) rename idea/testData/codeInsight/lineMarker/recursiveCall/{functionalExpression.kt => localFun.kt} (98%) diff --git a/compiler/backend/src/org/jetbrains/kotlin/codegen/ClosureCodegen.java b/compiler/backend/src/org/jetbrains/kotlin/codegen/ClosureCodegen.java index 7ed2381ea32..00d59916e42 100644 --- a/compiler/backend/src/org/jetbrains/kotlin/codegen/ClosureCodegen.java +++ b/compiler/backend/src/org/jetbrains/kotlin/codegen/ClosureCodegen.java @@ -152,7 +152,7 @@ public class ClosureCodegen extends MemberCodegen { @Nullable @Override protected ClassDescriptor classForInnerClassRecord() { - return JvmCodegenUtil.isLambdaWhichWillBeInlined(bindingContext, funDescriptor) ? null : classDescriptor; + return JvmCodegenUtil.isArgumentWhichWillBeInlined(bindingContext, funDescriptor) ? null : classDescriptor; } @Override diff --git a/compiler/backend/src/org/jetbrains/kotlin/codegen/ExpressionCodegen.java b/compiler/backend/src/org/jetbrains/kotlin/codegen/ExpressionCodegen.java index 58f4938e3e1..e5507e4c2d1 100644 --- a/compiler/backend/src/org/jetbrains/kotlin/codegen/ExpressionCodegen.java +++ b/compiler/backend/src/org/jetbrains/kotlin/codegen/ExpressionCodegen.java @@ -1849,7 +1849,7 @@ public class ExpressionCodegen extends JetVisitor implem if (isFunctionLiteral(descriptor)) { //non labeled return couldn't be local in lambda FunctionDescriptor containingFunction = - BindingContextUtils.getContainingFunctionSkipFunctionLiterals(descriptor, false).getFirst(); + BindingContextUtils.getContainingFunctionSkipFunctionLiterals(descriptor, true).getFirst(); //FIRST_FUN_LABEL to prevent clashing with existing labels return new NonLocalReturnInfo(typeMapper.mapReturnType(containingFunction), InlineCodegenUtil.FIRST_FUN_LABEL); } else { diff --git a/compiler/backend/src/org/jetbrains/kotlin/codegen/JvmCodegenUtil.java b/compiler/backend/src/org/jetbrains/kotlin/codegen/JvmCodegenUtil.java index 9824ea18c2e..660db46c628 100644 --- a/compiler/backend/src/org/jetbrains/kotlin/codegen/JvmCodegenUtil.java +++ b/compiler/backend/src/org/jetbrains/kotlin/codegen/JvmCodegenUtil.java @@ -230,10 +230,10 @@ public class JvmCodegenUtil { : descriptor; } - public static boolean isLambdaWhichWillBeInlined(@NotNull BindingContext bindingContext, @NotNull DeclarationDescriptor descriptor) { + public static boolean isArgumentWhichWillBeInlined(@NotNull BindingContext bindingContext, @NotNull DeclarationDescriptor descriptor) { PsiElement declaration = DescriptorToSourceUtils.descriptorToDeclaration(descriptor); - return InlineUtil.isFunctionalExpression(declaration) && - InlineUtil.isInlineLambda((JetFunction)declaration, bindingContext, false); + return InlineUtil.canBeInlineArgument(declaration) && + InlineUtil.isInlinedArgument((JetFunction) declaration, bindingContext, false); } @Nullable diff --git a/compiler/backend/src/org/jetbrains/kotlin/codegen/binding/CodegenBinding.java b/compiler/backend/src/org/jetbrains/kotlin/codegen/binding/CodegenBinding.java index fb185c097df..e5e9355c4af 100644 --- a/compiler/backend/src/org/jetbrains/kotlin/codegen/binding/CodegenBinding.java +++ b/compiler/backend/src/org/jetbrains/kotlin/codegen/binding/CodegenBinding.java @@ -174,7 +174,7 @@ public class CodegenBinding { // Note: at the moment this is needed for light classes only // TODO: refactor this out - if (enclosing != null && !JvmCodegenUtil.isLambdaWhichWillBeInlined(trace.getBindingContext(), classDescriptor)) { + if (enclosing != null && !JvmCodegenUtil.isArgumentWhichWillBeInlined(trace.getBindingContext(), classDescriptor)) { recordInnerClass(trace, enclosing, classDescriptor); } } diff --git a/compiler/backend/src/org/jetbrains/kotlin/codegen/inline/InlineCodegen.java b/compiler/backend/src/org/jetbrains/kotlin/codegen/inline/InlineCodegen.java index 061f38d1d03..1c755ed03a6 100644 --- a/compiler/backend/src/org/jetbrains/kotlin/codegen/inline/InlineCodegen.java +++ b/compiler/backend/src/org/jetbrains/kotlin/codegen/inline/InlineCodegen.java @@ -16,7 +16,6 @@ package org.jetbrains.kotlin.codegen.inline; -import com.google.common.collect.ImmutableSet; import com.intellij.openapi.vfs.VirtualFile; import com.intellij.psi.PsiElement; import com.intellij.psi.PsiFile; @@ -60,7 +59,6 @@ import java.util.*; import static org.jetbrains.kotlin.codegen.AsmUtil.getMethodAsmFlags; import static org.jetbrains.kotlin.codegen.AsmUtil.isPrimitive; import static org.jetbrains.kotlin.codegen.inline.InlineCodegenUtil.addInlineMarker; -import static org.jetbrains.kotlin.resolve.DescriptorUtils.isFunctionExpression; import static org.jetbrains.kotlin.resolve.DescriptorUtils.isFunctionLiteral; import static org.jetbrains.kotlin.resolve.calls.callUtil.CallUtilPackage.getResolvedCallWithAssert; diff --git a/compiler/frontend/src/org/jetbrains/kotlin/resolve/calls/checkers/CapturingInClosureChecker.kt b/compiler/frontend/src/org/jetbrains/kotlin/resolve/calls/checkers/CapturingInClosureChecker.kt index 3641eefce4c..6611164be24 100644 --- a/compiler/frontend/src/org/jetbrains/kotlin/resolve/calls/checkers/CapturingInClosureChecker.kt +++ b/compiler/frontend/src/org/jetbrains/kotlin/resolve/calls/checkers/CapturingInClosureChecker.kt @@ -69,9 +69,9 @@ class CapturingInClosureChecker : CallChecker { context: BindingContext, scopeContainer: DeclarationDescriptor, variableParent: DeclarationDescriptor ): Boolean { val scopeDeclaration = DescriptorToSourceUtils.descriptorToDeclaration(scopeContainer) - if (!InlineUtil.isFunctionalExpression(scopeDeclaration)) return false + if (!InlineUtil.canBeInlineArgument(scopeDeclaration)) return false - if (InlineUtil.isInlineLambda(scopeDeclaration as JetFunction, context, false)) { + if (InlineUtil.isInlinedArgument(scopeDeclaration as JetFunction, context, false)) { val scopeContainerParent = scopeContainer.getContainingDeclaration() assert(scopeContainerParent != null) { "parent is null for " + scopeContainer } return !isCapturedVariable(variableParent, scopeContainerParent) || isCapturedInInline(context, scopeContainerParent, variableParent) diff --git a/compiler/frontend/src/org/jetbrains/kotlin/resolve/inline/InlineUtil.java b/compiler/frontend/src/org/jetbrains/kotlin/resolve/inline/InlineUtil.java index 93030a98ac7..983deaf5047 100644 --- a/compiler/frontend/src/org/jetbrains/kotlin/resolve/inline/InlineUtil.java +++ b/compiler/frontend/src/org/jetbrains/kotlin/resolve/inline/InlineUtil.java @@ -102,8 +102,8 @@ public class InlineUtil { BindingContext bindingContext = trace.getBindingContext(); - while (isFunctionalExpression(containingFunction) && fromFunction != containingFunctionDescriptor) { - if (!isInlineLambda((JetFunction) containingFunction, bindingContext, true)) { + while (canBeInlineArgument(containingFunction) && fromFunction != containingFunctionDescriptor) { + if (!isInlinedArgument((JetFunction) containingFunction, bindingContext, true)) { return false; } @@ -117,20 +117,20 @@ public class InlineUtil { return fromFunction == containingFunctionDescriptor; } - public static boolean isInlineLambda( - @NotNull JetFunction functionalExpression, + public static boolean isInlinedArgument( + @NotNull JetFunction argument, @NotNull BindingContext bindingContext, boolean checkNonLocalReturn ) { - if (!isFunctionalExpression(functionalExpression)) return false; + if (!canBeInlineArgument(argument)) return false; - JetExpression call = JetPsiUtil.getParentCallIfPresent(functionalExpression); + JetExpression call = JetPsiUtil.getParentCallIfPresent(argument); if (call != null) { ResolvedCall resolvedCall = CallUtilPackage.getResolvedCall(call, bindingContext); if (resolvedCall != null && isInline(resolvedCall.getResultingDescriptor())) { - ValueArgument argument = CallUtilPackage.getValueArgumentForExpression(resolvedCall.getCall(), functionalExpression); - if (argument != null) { - ArgumentMapping mapping = resolvedCall.getArgumentMapping(argument); + ValueArgument valueArgument = CallUtilPackage.getValueArgumentForExpression(resolvedCall.getCall(), argument); + if (valueArgument != null) { + ArgumentMapping mapping = resolvedCall.getArgumentMapping(valueArgument); if (mapping instanceof ArgumentMatch) { ValueParameterDescriptor parameter = ((ArgumentMatch) mapping).getValueParameter(); if (isInlineLambdaParameter(parameter)) { @@ -143,7 +143,7 @@ public class InlineUtil { return false; } - public static boolean isFunctionalExpression(@Nullable PsiElement functionalExpression) { + public static boolean canBeInlineArgument(@Nullable PsiElement functionalExpression) { return functionalExpression instanceof JetFunctionLiteral || functionalExpression instanceof JetNamedFunction; } diff --git a/idea/src/org/jetbrains/kotlin/idea/codeInsight/CodeInsightUtils.java b/idea/src/org/jetbrains/kotlin/idea/codeInsight/CodeInsightUtils.java index 74a9eb15426..78f0cd46aec 100644 --- a/idea/src/org/jetbrains/kotlin/idea/codeInsight/CodeInsightUtils.java +++ b/idea/src/org/jetbrains/kotlin/idea/codeInsight/CodeInsightUtils.java @@ -27,11 +27,11 @@ import com.intellij.refactoring.util.CommonRefactoringUtil; import com.intellij.util.text.CharArrayUtil; import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.Nullable; -import org.jetbrains.kotlin.builtins.KotlinBuiltIns; import org.jetbrains.kotlin.psi.*; import org.jetbrains.kotlin.types.JetType; import java.util.ArrayList; +import java.util.Collections; import java.util.List; import static org.jetbrains.kotlin.builtins.KotlinBuiltIns.*; @@ -138,35 +138,37 @@ public class CodeInsightUtils { return element; } - @Nullable - public static PsiElement[] findElementsOfClassInRange(@NotNull PsiFile file, int startOffset, int endOffset, Class aClass) { + @NotNull + public static List findElementsOfClassInRange(@NotNull PsiFile file, int startOffset, int endOffset, Class ... classes) { PsiElement element1 = getElementAtOffsetIgnoreWhitespaceBefore(file, startOffset); PsiElement element2 = getElementAtOffsetIgnoreWhitespaceAfter(file, endOffset); - if (element1 == null || element2 == null) return PsiElement.EMPTY_ARRAY; + if (element1 == null || element2 == null) return Collections.emptyList(); startOffset = element1.getTextRange().getStartOffset(); endOffset = element2.getTextRange().getEndOffset(); PsiElement parent = PsiTreeUtil.findCommonParent(element1, element2); - if (parent == null) return PsiElement.EMPTY_ARRAY; + if (parent == null) return Collections.emptyList(); element1 = getTopmostParentInside(element1, parent); - if (startOffset != element1.getTextRange().getStartOffset()) return PsiElement.EMPTY_ARRAY; + if (startOffset != element1.getTextRange().getStartOffset()) return Collections.emptyList(); element2 = getTopmostParentInside(element2, parent); - if (endOffset != element2.getTextRange().getEndOffset()) return PsiElement.EMPTY_ARRAY; + if (endOffset != element2.getTextRange().getEndOffset()) return Collections.emptyList(); PsiElement stopElement = element2.getNextSibling(); - List array = new ArrayList(); + List result = new ArrayList(); for (PsiElement currentElement = element1; currentElement != stopElement && currentElement != null; currentElement = currentElement.getNextSibling()) { - if (aClass.isInstance(currentElement)) { - array.add(currentElement); + for (Class aClass : classes) { + if (aClass.isInstance(currentElement)) { + result.add(currentElement); + } + result.addAll(PsiTreeUtil.findChildrenOfType(currentElement, aClass)); } - array.addAll(PsiTreeUtil.findChildrenOfType(currentElement, aClass)); } - return PsiUtilCore.toPsiElementArray(array); + return result; } @NotNull diff --git a/idea/src/org/jetbrains/kotlin/idea/debugger/JetPositionManager.kt b/idea/src/org/jetbrains/kotlin/idea/debugger/JetPositionManager.kt index 9636d062922..90337ce93f6 100644 --- a/idea/src/org/jetbrains/kotlin/idea/debugger/JetPositionManager.kt +++ b/idea/src/org/jetbrains/kotlin/idea/debugger/JetPositionManager.kt @@ -83,9 +83,9 @@ public class JetPositionManager(private val myDebugProcess: DebugProcess) : Mult if (lineNumber >= 0) { - val lambdaIfInside = getLambdaOrFunIfInside(location, psiFile as JetFile, lineNumber) - if (lambdaIfInside != null) { - return SourcePosition.createFromElement(lambdaIfInside.getBodyExpression()) + val lambdaOrFunIfInside = getLambdaOrFunIfInside(location, psiFile as JetFile, lineNumber) + if (lambdaOrFunIfInside != null) { + return SourcePosition.createFromElement(lambdaOrFunIfInside.getBodyExpression()) } return SourcePosition.createFromLine(psiFile, lineNumber) } @@ -101,15 +101,11 @@ public class JetPositionManager(private val myDebugProcess: DebugProcess) : Mult val end = CodeInsightUtils.getEndLineOffset(file, lineNumber) if (start == null || end == null) return null - val functionLiterals: Array? = CodeInsightUtils.findElementsOfClassInRange(file, start, end, javaClass()) - val functionalExpression: Array? = CodeInsightUtils.findElementsOfClassInRange(file, start, end, javaClass()) - val literals = - if (functionLiterals == null) functionalExpression - else if (functionalExpression == null) functionLiterals - else functionLiterals.plus(functionalExpression).toTypedArray() + val literalsOrFunctions = CodeInsightUtils. + findElementsOfClassInRange(file, start, end, javaClass(), javaClass()). + filter { JetPsiUtil.getParentCallIfPresent(it as JetExpression) != null } - - if (literals == null || literals.size() == 0) return null; + if (literalsOrFunctions.isEmpty()) return null; val isInLibrary = LibraryUtil.findLibraryEntry(file.getVirtualFile(), file.getProject()) != null val typeMapper = if (!isInLibrary) @@ -118,7 +114,7 @@ public class JetPositionManager(private val myDebugProcess: DebugProcess) : Mult createTypeMapperForLibraryFile(file.findElementAt(start), file) val currentLocationClassName = JvmClassName.byFqNameWithoutInnerClasses(FqName(currentLocationFqName)).getInternalName() - for (literal in literals) { + for (literal in literalsOrFunctions) { val functionLiteral = literal as JetFunction if (isInlinedLambda(functionLiteral, typeMapper.getBindingContext())) { continue @@ -400,7 +396,7 @@ public class JetPositionManager(private val myDebugProcess: DebugProcess) : Mult } public fun isInlinedLambda(functionLiteral: JetFunction, context: BindingContext): Boolean { - return InlineUtil.isInlineLambda(functionLiteral, context, false) + return InlineUtil.isInlinedArgument(functionLiteral, context, false) } private fun createKeyForTypeMapper(file: JetFile) = PackagePartClassUtils.getPackagePartInternalName(file) diff --git a/idea/src/org/jetbrains/kotlin/idea/highlighter/KotlinHighlightExitPointsHandlerFactory.kt b/idea/src/org/jetbrains/kotlin/idea/highlighter/KotlinHighlightExitPointsHandlerFactory.kt index c508f68da83..573c9357ef4 100644 --- a/idea/src/org/jetbrains/kotlin/idea/highlighter/KotlinHighlightExitPointsHandlerFactory.kt +++ b/idea/src/org/jetbrains/kotlin/idea/highlighter/KotlinHighlightExitPointsHandlerFactory.kt @@ -84,9 +84,8 @@ private fun JetExpression.getRelevantFunction(): JetFunction? { (this.getTargetLabel()?.getReference()?.resolve() as? JetFunction)?.let { return it } } for (parent in parents(false)) { - when (parent) { - is JetFunctionLiteral, - is JetNamedFunction -> if (!InlineUtil.isInlineLambda(parent as JetFunction, parent.analyze(), false)) return parent + if (InlineUtil.canBeInlineArgument(parent) && !InlineUtil.isInlinedArgument(parent as JetFunction, parent.analyze(), false)) { + return parent as JetFunction } } return null diff --git a/idea/src/org/jetbrains/kotlin/idea/highlighter/KotlinRecursiveCallLineMarkerProvider.kt b/idea/src/org/jetbrains/kotlin/idea/highlighter/KotlinRecursiveCallLineMarkerProvider.kt index b082f616aa3..cdf616bead1 100644 --- a/idea/src/org/jetbrains/kotlin/idea/highlighter/KotlinRecursiveCallLineMarkerProvider.kt +++ b/idea/src/org/jetbrains/kotlin/idea/highlighter/KotlinRecursiveCallLineMarkerProvider.kt @@ -56,8 +56,8 @@ public class KotlinRecursiveCallLineMarkerProvider() : LineMarkerProvider { private fun getEnclosingFunction(element: JetElement): JetNamedFunction? { for (parent in element.parents(false)) { when (parent) { - is JetFunctionLiteral -> if (!InlineUtil.isInlineLambda(parent, parent.analyze(), false)) return null - is JetNamedFunction -> if (!InlineUtil.isInlineLambda(parent, parent.analyze(), false)) return parent + is JetFunctionLiteral -> if (!InlineUtil.isInlinedArgument(parent, parent.analyze(), false)) return null + is JetNamedFunction -> if (!InlineUtil.isInlinedArgument(parent, parent.analyze(), false)) return parent is JetClassOrObject -> return null } } diff --git a/idea/testData/codeInsight/lineMarker/recursiveCall/inInlinedFunctionExpression.kt b/idea/testData/codeInsight/lineMarker/recursiveCall/inInlinedFunctionExpression.kt index 91660fded15..432c5c7837c 100644 --- a/idea/testData/codeInsight/lineMarker/recursiveCall/inInlinedFunctionExpression.kt +++ b/idea/testData/codeInsight/lineMarker/recursiveCall/inInlinedFunctionExpression.kt @@ -1,5 +1,5 @@ fun f(a: Int) { - run(fun () { + run2(fun () { f(a - 1) }) } @@ -12,3 +12,5 @@ fun ff(a: Int) { inline fun run1(noinline f: () -> T): T { } +inline fun run2(f: () -> T): T { } + diff --git a/idea/testData/codeInsight/lineMarker/recursiveCall/functionalExpression.kt b/idea/testData/codeInsight/lineMarker/recursiveCall/localFun.kt similarity index 98% rename from idea/testData/codeInsight/lineMarker/recursiveCall/functionalExpression.kt rename to idea/testData/codeInsight/lineMarker/recursiveCall/localFun.kt index a4a3972d4e8..e27958dcd19 100644 --- a/idea/testData/codeInsight/lineMarker/recursiveCall/functionalExpression.kt +++ b/idea/testData/codeInsight/lineMarker/recursiveCall/localFun.kt @@ -5,4 +5,4 @@ fun test() { f(a-1) } } -} \ No newline at end of file +} diff --git a/idea/tests/org/jetbrains/kotlin/idea/codeInsight/LineMarkersTestGenerated.java b/idea/tests/org/jetbrains/kotlin/idea/codeInsight/LineMarkersTestGenerated.java index fa3aec3cda1..d4f211c0785 100644 --- a/idea/tests/org/jetbrains/kotlin/idea/codeInsight/LineMarkersTestGenerated.java +++ b/idea/tests/org/jetbrains/kotlin/idea/codeInsight/LineMarkersTestGenerated.java @@ -202,12 +202,6 @@ public class LineMarkersTestGenerated extends AbstractLineMarkersTest { doTest(fileName); } - @TestMetadata("functionalExpression.kt") - public void testFunctionalExpression() throws Exception { - String fileName = JetTestUtils.navigationMetadata("idea/testData/codeInsight/lineMarker/recursiveCall/functionalExpression.kt"); - doTest(fileName); - } - @TestMetadata("generic.kt") public void testGeneric() throws Exception { String fileName = JetTestUtils.navigationMetadata("idea/testData/codeInsight/lineMarker/recursiveCall/generic.kt"); @@ -238,6 +232,12 @@ public class LineMarkersTestGenerated extends AbstractLineMarkersTest { doTest(fileName); } + @TestMetadata("localFun.kt") + public void testLocalFun() throws Exception { + String fileName = JetTestUtils.navigationMetadata("idea/testData/codeInsight/lineMarker/recursiveCall/localFun.kt"); + doTest(fileName); + } + @TestMetadata("methodReference.kt") public void testMethodReference() throws Exception { String fileName = JetTestUtils.navigationMetadata("idea/testData/codeInsight/lineMarker/recursiveCall/methodReference.kt");