diff --git a/idea/src/org/jetbrains/kotlin/idea/internal/KotlinBytecodeToolWindow.java b/idea/src/org/jetbrains/kotlin/idea/internal/KotlinBytecodeToolWindow.java index 1e7c25868e9..6cd1b465080 100644 --- a/idea/src/org/jetbrains/kotlin/idea/internal/KotlinBytecodeToolWindow.java +++ b/idea/src/org/jetbrains/kotlin/idea/internal/KotlinBytecodeToolWindow.java @@ -197,12 +197,12 @@ public class KotlinBytecodeToolWindow extends JPanel implements Disposable { BindingContext bindingContextForFile = resolutionFacade.analyzeFullyAndGetResult(Collections.singletonList(jetFile)).getBindingContext(); - kotlin.Pair> result = DebuggerUtils.analyzeInlinedFunctions( + kotlin.Pair> result = DebuggerUtils.INSTANCE.analyzeInlinedFunctions( resolutionFacade, bindingContextForFile, jetFile, !enableInline ); BindingContext bindingContext = result.getFirst(); - List toProcess = result.getSecond(); + List toProcess = result.getSecond(); GenerationState.GenerateClassFilter generateClassFilter = new GenerationState.GenerateClassFilter() { diff --git a/idea/src/org/jetbrains/kotlin/idea/util/DebuggerUtils.kt b/idea/src/org/jetbrains/kotlin/idea/util/DebuggerUtils.kt index 8d210cedf8b..0f4ca5d4be1 100644 --- a/idea/src/org/jetbrains/kotlin/idea/util/DebuggerUtils.kt +++ b/idea/src/org/jetbrains/kotlin/idea/util/DebuggerUtils.kt @@ -14,215 +14,179 @@ * limitations under the License. */ -package org.jetbrains.kotlin.idea.util; +package org.jetbrains.kotlin.idea.util -import com.google.common.base.Predicate; -import com.google.common.collect.Collections2; -import com.google.common.collect.Iterables; -import com.google.common.collect.Sets; -import com.intellij.openapi.project.DumbService; -import com.intellij.openapi.project.Project; -import com.intellij.openapi.util.io.FileUtilRt; -import com.intellij.psi.PsiElement; -import com.intellij.psi.search.GlobalSearchScope; -import kotlin.Pair; -import org.jetbrains.annotations.NotNull; -import org.jetbrains.annotations.Nullable; -import org.jetbrains.kotlin.descriptors.CallableDescriptor; -import org.jetbrains.kotlin.descriptors.FunctionDescriptor; -import org.jetbrains.kotlin.descriptors.TypeParameterDescriptor; -import org.jetbrains.kotlin.idea.codeInsight.DescriptorToSourceUtilsIde; -import org.jetbrains.kotlin.idea.resolve.ResolutionFacade; -import org.jetbrains.kotlin.idea.stubindex.StaticFacadeIndexUtil; -import org.jetbrains.kotlin.name.FqName; -import org.jetbrains.kotlin.psi.*; -import org.jetbrains.kotlin.resolve.BindingContext; -import org.jetbrains.kotlin.resolve.CompositeBindingContext; -import org.jetbrains.kotlin.resolve.calls.model.ResolvedCall; -import org.jetbrains.kotlin.resolve.inline.InlineUtil; -import org.jetbrains.kotlin.resolve.jvm.JvmClassName; -import org.jetbrains.kotlin.resolve.lazy.BodyResolveMode; -import org.jetbrains.kotlin.serialization.deserialization.descriptors.DeserializedSimpleFunctionDescriptor; +import com.google.common.collect.Sets +import com.intellij.openapi.project.DumbService +import com.intellij.openapi.project.Project +import com.intellij.openapi.util.io.FileUtilRt +import com.intellij.psi.search.GlobalSearchScope +import org.jetbrains.kotlin.descriptors.CallableDescriptor +import org.jetbrains.kotlin.idea.codeInsight.DescriptorToSourceUtilsIde +import org.jetbrains.kotlin.idea.resolve.ResolutionFacade +import org.jetbrains.kotlin.idea.stubindex.PackageIndexUtil.findFilesWithExactPackage +import org.jetbrains.kotlin.idea.stubindex.StaticFacadeIndexUtil +import org.jetbrains.kotlin.psi.* +import org.jetbrains.kotlin.resolve.BindingContext +import org.jetbrains.kotlin.resolve.CompositeBindingContext +import org.jetbrains.kotlin.resolve.calls.model.ResolvedCall +import org.jetbrains.kotlin.resolve.inline.InlineUtil +import org.jetbrains.kotlin.resolve.jvm.JvmClassName +import org.jetbrains.kotlin.resolve.lazy.BodyResolveMode +import org.jetbrains.kotlin.serialization.deserialization.descriptors.DeserializedSimpleFunctionDescriptor +import java.util.* -import java.util.*; +object DebuggerUtils { -import static org.jetbrains.kotlin.idea.stubindex.PackageIndexUtil.findFilesWithExactPackage; + private val KOTLIN_EXTENSIONS = Sets.newHashSet("kt", "kts") -public class DebuggerUtils { - private DebuggerUtils() { - } + fun findSourceFileForClass( + project: Project, + searchScope: GlobalSearchScope, + className: JvmClassName, + fileName: String): KtFile? { + val extension = FileUtilRt.getExtension(fileName) + if (!KOTLIN_EXTENSIONS.contains(extension)) return null + if (DumbService.getInstance(project).isDumb) return null - private static final Set KOTLIN_EXTENSIONS = Sets.newHashSet("kt", "kts"); + val filesInPackage = findFilesWithExactPackage(className.packageFqName, searchScope, project) + val filesWithExactName = filesInPackage.filter { it.name == fileName } - @Nullable - public static KtFile findSourceFileForClass( - @NotNull Project project, - @NotNull GlobalSearchScope searchScope, - @NotNull JvmClassName className, - @NotNull final String fileName - ) { - String extension = FileUtilRt.getExtension(fileName); - if (!KOTLIN_EXTENSIONS.contains(extension)) return null; - if (DumbService.getInstance(project).isDumb()) return null; + if (filesWithExactName.isEmpty()) return null - Collection filesInPackage = findFilesWithExactPackage(className.getPackageFqName(), searchScope, project); - Collection filesWithExactName = Collections2.filter(filesInPackage, new Predicate() { - @Override - public boolean apply(@Nullable KtFile file) { - return file != null && file.getName().equals(fileName); - } - }); - - if (filesWithExactName.isEmpty()) return null; - - if (filesWithExactName.size() == 1) { - return filesWithExactName.iterator().next(); + if (filesWithExactName.size == 1) { + return filesWithExactName.single() } // Static facade or inner class of such facade? - FqName partFqName = className.getFqNameForClassNameWithoutDollars(); - Collection filesForPart = StaticFacadeIndexUtil.findFilesForFilePart(partFqName, searchScope, project); + val partFqName = className.fqNameForClassNameWithoutDollars + val filesForPart = StaticFacadeIndexUtil.findFilesForFilePart(partFqName, searchScope, project) if (!filesForPart.isEmpty()) { - for (KtFile file : filesForPart) { - if (file.getName().equals(fileName)) { - return file; + for (file in filesForPart) { + if (file.name == fileName) { + return file } } // Do not fall back to decompiled files (which have different name). - return null; + return null } - return filesWithExactName.iterator().next(); + return filesWithExactName.first() } - @NotNull - public static Pair> analyzeInlinedFunctions( - @NotNull ResolutionFacade resolutionFacadeForFile, - @NotNull BindingContext bindingContextForFile, - @NotNull KtFile file, - boolean analyzeOnlyReifiedInlineFunctions - ) { - Set analyzedElements = new HashSet(); - BindingContext context = analyzeElementWithInline( + fun analyzeInlinedFunctions( + resolutionFacadeForFile: ResolutionFacade, + bindingContextForFile: BindingContext, + file: KtFile, + analyzeOnlyReifiedInlineFunctions: Boolean + ): Pair> { + val analyzedElements = HashSet() + val context = analyzeElementWithInline( resolutionFacadeForFile, bindingContextForFile, file, 1, analyzedElements, - !analyzeOnlyReifiedInlineFunctions); + !analyzeOnlyReifiedInlineFunctions) //We processing another files just to annotate anonymous classes within their inline functions //Bytecode not produced for them cause of filtering via generateClassFilter - Set toProcess = new LinkedHashSet(); - toProcess.add(file); + val toProcess = LinkedHashSet() + toProcess.add(file) - for (KtElement collectedElement : analyzedElements) { - KtFile containingFile = collectedElement.getContainingKtFile(); - toProcess.add(containingFile); + for (collectedElement in analyzedElements) { + val containingFile = collectedElement.getContainingKtFile() + toProcess.add(containingFile) } - return new Pair>(context, new ArrayList(toProcess)); + return Pair>(context, ArrayList(toProcess)) } - @NotNull - public static Collection analyzeElementWithInline( - @NotNull ResolutionFacade resolutionFacade, - @NotNull BindingContext bindingContext, - @NotNull KtNamedFunction function, - boolean analyzeInlineFunctions - ) { - Set analyzedElements = new HashSet(); - analyzeElementWithInline(resolutionFacade, bindingContext, function, 1, analyzedElements, !analyzeInlineFunctions); - return analyzedElements; + fun analyzeElementWithInline( + resolutionFacade: ResolutionFacade, + bindingContext: BindingContext, + function: KtNamedFunction, + analyzeInlineFunctions: Boolean): Collection { + val analyzedElements = HashSet() + analyzeElementWithInline(resolutionFacade, bindingContext, function, 1, analyzedElements, !analyzeInlineFunctions) + return analyzedElements } - @NotNull - private static BindingContext analyzeElementWithInline( - @NotNull ResolutionFacade resolutionFacade, - @NotNull final BindingContext bindingContext, - @NotNull KtElement element, - int deep, - @NotNull final Set analyzedElements, - final boolean analyzeInlineFunctions - ) { - final Project project = element.getProject(); - final Set collectedElements = new HashSet(); + private fun analyzeElementWithInline( + resolutionFacade: ResolutionFacade, + bindingContext: BindingContext, + element: KtElement, + deep: Int, + analyzedElements: MutableSet, + analyzeInlineFunctions: Boolean): BindingContext { + val project = element.project + val collectedElements = HashSet() - element.accept(new KtTreeVisitorVoid() { - @Override - public void visitExpression(@NotNull KtExpression expression) { - super.visitExpression(expression); + element.accept(object : KtTreeVisitorVoid() { + override fun visitExpression(expression: KtExpression) { + super.visitExpression(expression) - Call call = bindingContext.get(BindingContext.CALL, expression); - if (call == null) return; + val call = bindingContext.get(BindingContext.CALL, expression) ?: return - ResolvedCall resolvedCall = bindingContext.get(BindingContext.RESOLVED_CALL, call); - checkResolveCall(resolvedCall); + val resolvedCall = bindingContext.get(BindingContext.RESOLVED_CALL, call) + checkResolveCall(resolvedCall) } - @Override - public void visitMultiDeclaration(@NotNull KtMultiDeclaration multiDeclaration) { - super.visitMultiDeclaration(multiDeclaration); + override fun visitMultiDeclaration(multiDeclaration: KtMultiDeclaration) { + super.visitMultiDeclaration(multiDeclaration) - for (KtMultiDeclarationEntry entry : multiDeclaration.getEntries()) { - ResolvedCall resolvedCall = - bindingContext.get(BindingContext.COMPONENT_RESOLVED_CALL, entry); - checkResolveCall(resolvedCall); + for (entry in multiDeclaration.entries) { + val resolvedCall = bindingContext.get(BindingContext.COMPONENT_RESOLVED_CALL, entry) + checkResolveCall(resolvedCall) } } - @Override - public void visitForExpression(@NotNull KtForExpression expression) { - super.visitForExpression(expression); + override fun visitForExpression(expression: KtForExpression) { + super.visitForExpression(expression) - checkResolveCall(bindingContext.get(BindingContext.LOOP_RANGE_ITERATOR_RESOLVED_CALL, expression.getLoopRange())); - checkResolveCall(bindingContext.get(BindingContext.LOOP_RANGE_HAS_NEXT_RESOLVED_CALL, expression.getLoopRange())); - checkResolveCall(bindingContext.get(BindingContext.LOOP_RANGE_NEXT_RESOLVED_CALL, expression.getLoopRange())); + checkResolveCall(bindingContext.get(BindingContext.LOOP_RANGE_ITERATOR_RESOLVED_CALL, expression.loopRange)) + checkResolveCall(bindingContext.get(BindingContext.LOOP_RANGE_HAS_NEXT_RESOLVED_CALL, expression.loopRange)) + checkResolveCall(bindingContext.get(BindingContext.LOOP_RANGE_NEXT_RESOLVED_CALL, expression.loopRange)) } - private void checkResolveCall(ResolvedCall resolvedCall) { - if (resolvedCall == null) return; + private fun checkResolveCall(resolvedCall: ResolvedCall<*>?) { + if (resolvedCall == null) return - CallableDescriptor descriptor = resolvedCall.getResultingDescriptor(); - if (descriptor instanceof DeserializedSimpleFunctionDescriptor) return; + val descriptor = resolvedCall.resultingDescriptor + if (descriptor is DeserializedSimpleFunctionDescriptor) return if (InlineUtil.isInline(descriptor) && (analyzeInlineFunctions || hasReifiedTypeParameters(descriptor))) { - PsiElement declaration = DescriptorToSourceUtilsIde.INSTANCE$.getAnyDeclaration(project, descriptor); - if (declaration != null && declaration instanceof KtNamedFunction && !analyzedElements.contains(declaration)) { - collectedElements.add((KtNamedFunction) declaration); + val declaration = DescriptorToSourceUtilsIde.getAnyDeclaration(project, descriptor) + if (declaration != null && declaration is KtNamedFunction && !analyzedElements.contains(declaration)) { + collectedElements.add(declaration) } } } - }); + }) - analyzedElements.add(element); + analyzedElements.add(element) if (!collectedElements.isEmpty() && deep < 10) { - List innerContexts = new ArrayList(); - for (KtNamedFunction inlineFunctions : collectedElements) { - KtExpression body = inlineFunctions.getBodyExpression(); + val innerContexts = ArrayList() + for (inlineFunctions in collectedElements) { + val body = inlineFunctions.bodyExpression if (body != null) { - BindingContext bindingContextForFunction = resolutionFacade.analyze(body, BodyResolveMode.FULL); + val bindingContextForFunction = resolutionFacade.analyze(body, BodyResolveMode.FULL) innerContexts.add(analyzeElementWithInline(resolutionFacade, bindingContextForFunction, inlineFunctions, deep + 1, - analyzedElements, analyzeInlineFunctions)); + analyzedElements, analyzeInlineFunctions)) } } - innerContexts.add(bindingContext); + innerContexts.add(bindingContext) - analyzedElements.addAll(collectedElements); - return CompositeBindingContext.Companion.create(innerContexts); + analyzedElements.addAll(collectedElements) + return CompositeBindingContext.create(innerContexts) } - return bindingContext; + return bindingContext } - private static boolean hasReifiedTypeParameters(CallableDescriptor descriptor) { - return Iterables.any(descriptor.getTypeParameters(), new Predicate() { - @Override - public boolean apply(TypeParameterDescriptor input) { - return input.isReified(); - } - }); + private fun hasReifiedTypeParameters(descriptor: CallableDescriptor): Boolean { + return descriptor.typeParameters.any() { it.isReified } } }