Debugger: fix breakpoints in files with JvmName annotation
Drop unnessecary logic about part classes with hashcodes #KT-9480 Fixed
This commit is contained in:
@@ -41,6 +41,8 @@ import org.jetbrains.kotlin.codegen.state.GenerationState
|
|||||||
import org.jetbrains.kotlin.codegen.state.JetTypeMapper
|
import org.jetbrains.kotlin.codegen.state.JetTypeMapper
|
||||||
import org.jetbrains.kotlin.descriptors.ClassDescriptor
|
import org.jetbrains.kotlin.descriptors.ClassDescriptor
|
||||||
import org.jetbrains.kotlin.descriptors.PropertyDescriptor
|
import org.jetbrains.kotlin.descriptors.PropertyDescriptor
|
||||||
|
import org.jetbrains.kotlin.fileClasses.NoResolveFileClassesProvider
|
||||||
|
import org.jetbrains.kotlin.fileClasses.getFileClassInternalName
|
||||||
import org.jetbrains.kotlin.idea.caches.resolve.analyzeAndGetResult
|
import org.jetbrains.kotlin.idea.caches.resolve.analyzeAndGetResult
|
||||||
import org.jetbrains.kotlin.idea.caches.resolve.analyzeFullyAndGetResult
|
import org.jetbrains.kotlin.idea.caches.resolve.analyzeFullyAndGetResult
|
||||||
import org.jetbrains.kotlin.idea.codeInsight.CodeInsightUtils
|
import org.jetbrains.kotlin.idea.codeInsight.CodeInsightUtils
|
||||||
@@ -50,10 +52,8 @@ import org.jetbrains.kotlin.idea.util.DebuggerUtils
|
|||||||
import org.jetbrains.kotlin.idea.util.ProjectRootsUtil
|
import org.jetbrains.kotlin.idea.util.ProjectRootsUtil
|
||||||
import org.jetbrains.kotlin.idea.util.application.runReadAction
|
import org.jetbrains.kotlin.idea.util.application.runReadAction
|
||||||
import org.jetbrains.kotlin.load.kotlin.PackageClassUtils
|
import org.jetbrains.kotlin.load.kotlin.PackageClassUtils
|
||||||
import org.jetbrains.kotlin.load.kotlin.PackagePartClassUtils
|
|
||||||
import org.jetbrains.kotlin.name.FqName
|
import org.jetbrains.kotlin.name.FqName
|
||||||
import org.jetbrains.kotlin.psi.*
|
import org.jetbrains.kotlin.psi.*
|
||||||
import org.jetbrains.kotlin.psi.psiUtil.getElementTextWithContext
|
|
||||||
import org.jetbrains.kotlin.resolve.BindingContext
|
import org.jetbrains.kotlin.resolve.BindingContext
|
||||||
import org.jetbrains.kotlin.resolve.inline.InlineUtil
|
import org.jetbrains.kotlin.resolve.inline.InlineUtil
|
||||||
import org.jetbrains.kotlin.resolve.jvm.JvmClassName
|
import org.jetbrains.kotlin.resolve.jvm.JvmClassName
|
||||||
@@ -80,7 +80,7 @@ public class JetPositionManager(private val myDebugProcess: DebugProcess) : Mult
|
|||||||
val javaClassName = JvmClassName.byInternalName(defaultInternalName(location))
|
val javaClassName = JvmClassName.byInternalName(defaultInternalName(location))
|
||||||
val project = myDebugProcess.project
|
val project = myDebugProcess.project
|
||||||
|
|
||||||
val defaultPsiFile = DebuggerUtils.findSourceFileForClass(project, GlobalSearchScope.allScope(project), javaClassName, javaSourceFileName, 0)
|
val defaultPsiFile = DebuggerUtils.findSourceFileForClass(project, GlobalSearchScope.allScope(project), javaClassName, javaSourceFileName)
|
||||||
if (defaultPsiFile != null) {
|
if (defaultPsiFile != null) {
|
||||||
return SourcePosition.createFromLine(defaultPsiFile, 0)
|
return SourcePosition.createFromLine(defaultPsiFile, 0)
|
||||||
}
|
}
|
||||||
@@ -178,7 +178,7 @@ public class JetPositionManager(private val myDebugProcess: DebugProcess) : Mult
|
|||||||
|
|
||||||
val project = myDebugProcess.project
|
val project = myDebugProcess.project
|
||||||
|
|
||||||
return DebuggerUtils.findSourceFileForClass(project, GlobalSearchScope.allScope(project), className, sourceName, location.lineNumber() - 1)
|
return DebuggerUtils.findSourceFileForClass(project, GlobalSearchScope.allScope(project), className, sourceName)
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun defaultInternalName(location: Location): String {
|
private fun defaultInternalName(location: Location): String {
|
||||||
@@ -375,19 +375,7 @@ public class JetPositionManager(private val myDebugProcess: DebugProcess) : Mult
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (isInLibrary) {
|
return PositionedElement(NoResolveFileClassesProvider.getFileClassInternalName(file), element)
|
||||||
val elementAtForLibraryFile =
|
|
||||||
if (element is JetDeclaration) element
|
|
||||||
else PsiTreeUtil.getParentOfType(element, JetDeclaration::class.java)
|
|
||||||
|
|
||||||
assert(elementAtForLibraryFile != null) {
|
|
||||||
"Couldn't find element at breakpoint for library file " + file.name +
|
|
||||||
(if (notPositionedElement == null) "" else ", notPositionedElement = " + notPositionedElement.getElementTextWithContext())
|
|
||||||
}
|
|
||||||
return PositionedElement(findPackagePartInternalNameForLibraryFile(elementAtForLibraryFile!!), elementAtForLibraryFile)
|
|
||||||
}
|
|
||||||
|
|
||||||
return PositionedElement(PackagePartClassUtils.getPackagePartInternalName(file), element)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private val TYPES_TO_CALCULATE_CLASSNAME: Array<Class<out JetElement>> =
|
private val TYPES_TO_CALCULATE_CLASSNAME: Array<Class<out JetElement>> =
|
||||||
@@ -439,7 +427,7 @@ public class JetPositionManager(private val myDebugProcess: DebugProcess) : Mult
|
|||||||
return InlineUtil.isInlinedArgument(functionLiteral, context, false)
|
return InlineUtil.isInlinedArgument(functionLiteral, context, false)
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun createKeyForTypeMapper(file: JetFile) = PackagePartClassUtils.getPackagePartInternalName(file)
|
private fun createKeyForTypeMapper(file: JetFile) = NoResolveFileClassesProvider.getFileClassInternalName(file)
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun findInlinedCalls(element: PsiElement?, jetFile: PsiFile?): List<String> {
|
private fun findInlinedCalls(element: PsiElement?, jetFile: PsiFile?): List<String> {
|
||||||
|
|||||||
-129
@@ -1,129 +0,0 @@
|
|||||||
/*
|
|
||||||
* Copyright 2010-2015 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.kotlin.idea.debugger
|
|
||||||
|
|
||||||
import com.intellij.openapi.diagnostic.Logger
|
|
||||||
import com.intellij.openapi.module.impl.scopes.JdkScope
|
|
||||||
import com.intellij.openapi.module.impl.scopes.LibraryScope
|
|
||||||
import com.intellij.openapi.roots.JdkOrderEntry
|
|
||||||
import com.intellij.openapi.roots.LibraryOrderEntry
|
|
||||||
import com.intellij.openapi.roots.libraries.LibraryUtil
|
|
||||||
import com.intellij.psi.search.FilenameIndex
|
|
||||||
import org.jetbrains.kotlin.descriptors.CallableDescriptor
|
|
||||||
import org.jetbrains.kotlin.descriptors.DeclarationDescriptor
|
|
||||||
import org.jetbrains.kotlin.descriptors.FunctionDescriptor
|
|
||||||
import org.jetbrains.kotlin.descriptors.PropertyDescriptor
|
|
||||||
import org.jetbrains.kotlin.fileClasses.JvmFileClassUtil
|
|
||||||
import org.jetbrains.kotlin.idea.caches.resolve.resolveToDescriptor
|
|
||||||
import org.jetbrains.kotlin.incremental.components.NoLookupLocation
|
|
||||||
import org.jetbrains.kotlin.load.kotlin.PackagePartClassUtils
|
|
||||||
import org.jetbrains.kotlin.psi.JetDeclaration
|
|
||||||
import org.jetbrains.kotlin.psi.JetElement
|
|
||||||
import org.jetbrains.kotlin.psi.psiUtil.getElementTextWithContext
|
|
||||||
import org.jetbrains.kotlin.renderer.DescriptorRenderer
|
|
||||||
import org.jetbrains.kotlin.resolve.descriptorUtil.module
|
|
||||||
import org.jetbrains.kotlin.resolve.jvm.JvmClassName
|
|
||||||
import org.jetbrains.kotlin.serialization.deserialization.descriptors.DeserializedCallableMemberDescriptor
|
|
||||||
|
|
||||||
private val LOG = Logger.getInstance("org.jetbrains.kotlin.idea.debugger")
|
|
||||||
|
|
||||||
/**
|
|
||||||
* This method finds class name for top-level declaration in source file attached to library.
|
|
||||||
* The problem is that package-part class file has hash in className and it depends on machine where library was built,
|
|
||||||
* so we couldn't predict it.
|
|
||||||
* 1. find all .class files with package-part prefix, if there is one - return it
|
|
||||||
* 2. find all descriptors with same signature, if there is one - return it
|
|
||||||
* 3. else -> return null, because it means that there is more than one function with same signature in project
|
|
||||||
*/
|
|
||||||
fun findPackagePartInternalNameForLibraryFile(topLevelDeclaration: JetDeclaration): String? {
|
|
||||||
val packagePartFile = findPackagePartFileNamesForElement(topLevelDeclaration).singleOrNull()
|
|
||||||
if (packagePartFile != null) return packagePartFile
|
|
||||||
|
|
||||||
|
|
||||||
val descriptor = topLevelDeclaration.resolveToDescriptor()
|
|
||||||
if (descriptor !is CallableDescriptor) return null
|
|
||||||
|
|
||||||
val packageFqName = topLevelDeclaration.getContainingJetFile().getPackageFqName()
|
|
||||||
val packageDescriptor = descriptor.module.getPackage(packageFqName)
|
|
||||||
val descFromSourceText = render(descriptor)
|
|
||||||
|
|
||||||
val descriptors: Collection<CallableDescriptor> = when (descriptor) {
|
|
||||||
is FunctionDescriptor -> packageDescriptor.memberScope.getFunctions(descriptor.name, NoLookupLocation.FROM_IDE)
|
|
||||||
is PropertyDescriptor -> packageDescriptor.memberScope.getProperties(descriptor.name, NoLookupLocation.FROM_IDE)
|
|
||||||
else -> {
|
|
||||||
reportError(topLevelDeclaration, descriptor)
|
|
||||||
listOf()
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
val deserializedDescriptor = descriptors
|
|
||||||
.filterIsInstance<DeserializedCallableMemberDescriptor>()
|
|
||||||
.filter { render(it) == descFromSourceText }
|
|
||||||
.singleOrNull()
|
|
||||||
|
|
||||||
if (deserializedDescriptor == null) {
|
|
||||||
reportError(topLevelDeclaration, descriptor)
|
|
||||||
return null
|
|
||||||
}
|
|
||||||
|
|
||||||
val implClassName = JvmFileClassUtil.getImplClassName(deserializedDescriptor)
|
|
||||||
if (implClassName != null) {
|
|
||||||
return JvmClassName.byFqNameWithoutInnerClasses(packageFqName.child(implClassName)).getInternalName()
|
|
||||||
}
|
|
||||||
|
|
||||||
return null
|
|
||||||
}
|
|
||||||
|
|
||||||
private fun findPackagePartFileNamesForElement(elementAt: JetElement): List<String> {
|
|
||||||
val project = elementAt.getProject()
|
|
||||||
val file = elementAt.getContainingJetFile()
|
|
||||||
|
|
||||||
val packagePartName = PackagePartClassUtils.getPackagePartFqName(file).shortName().asString()
|
|
||||||
val packagePartNameWoHash = packagePartName.substring(0, packagePartName.lastIndexOf("$") + 1)
|
|
||||||
|
|
||||||
val libraryEntry = LibraryUtil.findLibraryEntry(file.getVirtualFile(), project)
|
|
||||||
val scope = if (libraryEntry is LibraryOrderEntry){
|
|
||||||
LibraryScope(project, libraryEntry.getLibrary() ?: throw AssertionError("Cannot find library for file ${file.getVirtualFile()?.getPath()}"))
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
JdkScope(project, libraryEntry as JdkOrderEntry)
|
|
||||||
}
|
|
||||||
|
|
||||||
val packagePartFiles = FilenameIndex.getAllFilenames(project).asSequence().filter {
|
|
||||||
it.startsWith(packagePartNameWoHash) && it.endsWith(".class") &&
|
|
||||||
!it.substringAfter(packagePartNameWoHash).contains("\$")
|
|
||||||
}.flatMap {
|
|
||||||
FilenameIndex.getVirtualFilesByName(project, it, scope).asSequence()
|
|
||||||
}.map {
|
|
||||||
val packageFqName = file.getPackageFqName()
|
|
||||||
if (packageFqName.isRoot()) {
|
|
||||||
it.getNameWithoutExtension()
|
|
||||||
} else {
|
|
||||||
"${packageFqName.asString()}.${it.getNameWithoutExtension()}"
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return packagePartFiles.toList()
|
|
||||||
}
|
|
||||||
|
|
||||||
private fun render(desc: DeclarationDescriptor) = DescriptorRenderer.FQ_NAMES_IN_TYPES.render(desc)
|
|
||||||
|
|
||||||
private fun reportError(element: JetElement, descriptor: CallableDescriptor?) {
|
|
||||||
LOG.error("Couldn't calculate class name for element in library scope:\n" +
|
|
||||||
element.getElementTextWithContext() +
|
|
||||||
if (descriptor != null) "\ndescriptor = ${render(descriptor)}" else ""
|
|
||||||
)
|
|
||||||
}
|
|
||||||
@@ -63,7 +63,7 @@ public class JetExceptionFilter implements Filter {
|
|||||||
String internalName = fullyQualifiedName.replace('.', '/');
|
String internalName = fullyQualifiedName.replace('.', '/');
|
||||||
JvmClassName jvmClassName = JvmClassName.byInternalName(internalName);
|
JvmClassName jvmClassName = JvmClassName.byInternalName(internalName);
|
||||||
|
|
||||||
JetFile file = DebuggerUtils.findSourceFileForClass(project, searchScope, jvmClassName, fileName, lineNumber);
|
JetFile file = DebuggerUtils.findSourceFileForClass(project, searchScope, jvmClassName, fileName);
|
||||||
|
|
||||||
if (file == null) return null;
|
if (file == null) return null;
|
||||||
VirtualFile virtualFile = file.getVirtualFile();
|
VirtualFile virtualFile = file.getVirtualFile();
|
||||||
|
|||||||
@@ -22,11 +22,9 @@ import com.google.common.collect.Iterables;
|
|||||||
import com.google.common.collect.Sets;
|
import com.google.common.collect.Sets;
|
||||||
import com.intellij.openapi.project.DumbService;
|
import com.intellij.openapi.project.DumbService;
|
||||||
import com.intellij.openapi.project.Project;
|
import com.intellij.openapi.project.Project;
|
||||||
import com.intellij.openapi.roots.libraries.LibraryUtil;
|
|
||||||
import com.intellij.openapi.util.io.FileUtilRt;
|
import com.intellij.openapi.util.io.FileUtilRt;
|
||||||
import com.intellij.psi.PsiElement;
|
import com.intellij.psi.PsiElement;
|
||||||
import com.intellij.psi.search.GlobalSearchScope;
|
import com.intellij.psi.search.GlobalSearchScope;
|
||||||
import com.intellij.psi.util.PsiTreeUtil;
|
|
||||||
import kotlin.KotlinPackage;
|
import kotlin.KotlinPackage;
|
||||||
import kotlin.Pair;
|
import kotlin.Pair;
|
||||||
import kotlin.jvm.functions.Function1;
|
import kotlin.jvm.functions.Function1;
|
||||||
@@ -35,13 +33,10 @@ import org.jetbrains.annotations.Nullable;
|
|||||||
import org.jetbrains.kotlin.descriptors.CallableDescriptor;
|
import org.jetbrains.kotlin.descriptors.CallableDescriptor;
|
||||||
import org.jetbrains.kotlin.descriptors.FunctionDescriptor;
|
import org.jetbrains.kotlin.descriptors.FunctionDescriptor;
|
||||||
import org.jetbrains.kotlin.descriptors.TypeParameterDescriptor;
|
import org.jetbrains.kotlin.descriptors.TypeParameterDescriptor;
|
||||||
import org.jetbrains.kotlin.idea.codeInsight.CodeInsightUtils;
|
|
||||||
import org.jetbrains.kotlin.idea.codeInsight.DescriptorToSourceUtilsIde;
|
import org.jetbrains.kotlin.idea.codeInsight.DescriptorToSourceUtilsIde;
|
||||||
import org.jetbrains.kotlin.idea.debugger.DebuggerPackage;
|
|
||||||
import org.jetbrains.kotlin.idea.resolve.ResolutionFacade;
|
import org.jetbrains.kotlin.idea.resolve.ResolutionFacade;
|
||||||
import org.jetbrains.kotlin.idea.stubindex.StaticFacadeIndexUtil;
|
import org.jetbrains.kotlin.idea.stubindex.StaticFacadeIndexUtil;
|
||||||
import org.jetbrains.kotlin.load.kotlin.PackageClassUtils;
|
import org.jetbrains.kotlin.load.kotlin.PackageClassUtils;
|
||||||
import org.jetbrains.kotlin.load.kotlin.PackagePartClassUtils;
|
|
||||||
import org.jetbrains.kotlin.name.FqName;
|
import org.jetbrains.kotlin.name.FqName;
|
||||||
import org.jetbrains.kotlin.psi.*;
|
import org.jetbrains.kotlin.psi.*;
|
||||||
import org.jetbrains.kotlin.resolve.BindingContext;
|
import org.jetbrains.kotlin.resolve.BindingContext;
|
||||||
@@ -66,9 +61,8 @@ public class DebuggerUtils {
|
|||||||
public static JetFile findSourceFileForClass(
|
public static JetFile findSourceFileForClass(
|
||||||
@NotNull Project project,
|
@NotNull Project project,
|
||||||
@NotNull GlobalSearchScope searchScope,
|
@NotNull GlobalSearchScope searchScope,
|
||||||
@NotNull final JvmClassName className,
|
@NotNull JvmClassName className,
|
||||||
@NotNull final String fileName,
|
@NotNull final String fileName
|
||||||
final int lineNumber
|
|
||||||
) {
|
) {
|
||||||
String extension = FileUtilRt.getExtension(fileName);
|
String extension = FileUtilRt.getExtension(fileName);
|
||||||
if (!KOTLIN_EXTENSIONS.contains(extension)) return null;
|
if (!KOTLIN_EXTENSIONS.contains(extension)) return null;
|
||||||
@@ -113,66 +107,15 @@ public class DebuggerUtils {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (isPackagePartClassName(className)) {
|
|
||||||
JetFile file = getFileForPackagePartPrefixedName(filesWithExactName, className.getInternalName());
|
|
||||||
if (file != null) {
|
|
||||||
return file;
|
|
||||||
}
|
|
||||||
|
|
||||||
boolean isInLibrary = KotlinPackage.all(filesWithExactName, new Function1<JetFile, Boolean>() {
|
|
||||||
@Override
|
|
||||||
public Boolean invoke(JetFile file) {
|
|
||||||
return LibraryUtil.findLibraryEntry(file.getVirtualFile(), file.getProject()) != null;
|
|
||||||
}
|
|
||||||
});
|
|
||||||
|
|
||||||
if (isInLibrary) {
|
|
||||||
return KotlinPackage.singleOrNull(KotlinPackage.filter(filesWithExactName, new Function1<JetFile, Boolean>() {
|
|
||||||
@Override
|
|
||||||
public Boolean invoke(JetFile file) {
|
|
||||||
Integer startLineOffset = CodeInsightUtils.getStartLineOffset(file, lineNumber);
|
|
||||||
assert startLineOffset != null : "Cannot find start line offset for file " + file.getName() + ", line " +
|
|
||||||
lineNumber;
|
|
||||||
JetDeclaration elementAt = PsiTreeUtil.getParentOfType(file.findElementAt(startLineOffset), JetDeclaration.class);
|
|
||||||
return elementAt != null &&
|
|
||||||
className.getInternalName().equals(DebuggerPackage.findPackagePartInternalNameForLibraryFile(elementAt));
|
|
||||||
}
|
|
||||||
}));
|
|
||||||
}
|
|
||||||
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
|
|
||||||
return filesWithExactName.iterator().next();
|
return filesWithExactName.iterator().next();
|
||||||
}
|
}
|
||||||
|
|
||||||
private static boolean isPackagePartClassName(JvmClassName className) {
|
|
||||||
String packageName = PackageClassUtils.getPackageClassInternalName(className.getPackageFqName());
|
|
||||||
|
|
||||||
String internalName = className.getInternalName();
|
|
||||||
return !internalName.equals(packageName) && internalName.startsWith(packageName);
|
|
||||||
}
|
|
||||||
|
|
||||||
private static boolean isPackageClassName(JvmClassName className) {
|
private static boolean isPackageClassName(JvmClassName className) {
|
||||||
String packageName = PackageClassUtils.getPackageClassInternalName(className.getPackageFqName());
|
String packageName = PackageClassUtils.getPackageClassInternalName(className.getPackageFqName());
|
||||||
|
|
||||||
return packageName.equals(className.getInternalName());
|
return packageName.equals(className.getInternalName());
|
||||||
}
|
}
|
||||||
|
|
||||||
@Nullable
|
|
||||||
private static JetFile getFileForPackagePartPrefixedName(
|
|
||||||
@NotNull Collection<JetFile> allPackageFiles,
|
|
||||||
@NotNull String classInternalName
|
|
||||||
) {
|
|
||||||
for (JetFile file : allPackageFiles) {
|
|
||||||
String packagePartInternalName = PackagePartClassUtils.getPackagePartInternalName(file);
|
|
||||||
if (classInternalName.startsWith(packagePartInternalName)) {
|
|
||||||
return file;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
|
|
||||||
@NotNull
|
@NotNull
|
||||||
public static Pair<BindingContext, List<JetFile>> analyzeInlinedFunctions(
|
public static Pair<BindingContext, List<JetFile>> analyzeInlinedFunctions(
|
||||||
@NotNull ResolutionFacade resolutionFacadeForFile,
|
@NotNull ResolutionFacade resolutionFacadeForFile,
|
||||||
|
|||||||
@@ -0,0 +1,6 @@
|
|||||||
|
@file:JvmName("ABC")
|
||||||
|
package a
|
||||||
|
|
||||||
|
fun foo() {
|
||||||
|
"" // a/ABC
|
||||||
|
}
|
||||||
@@ -28,23 +28,27 @@ import com.intellij.debugger.jdi.VirtualMachineProxyImpl;
|
|||||||
import com.intellij.openapi.application.ApplicationManager;
|
import com.intellij.openapi.application.ApplicationManager;
|
||||||
import com.intellij.openapi.project.Project;
|
import com.intellij.openapi.project.Project;
|
||||||
import com.intellij.openapi.util.text.StringUtil;
|
import com.intellij.openapi.util.text.StringUtil;
|
||||||
import com.intellij.openapi.vfs.VirtualFile;
|
import com.intellij.testFramework.LightProjectDescriptor;
|
||||||
import com.intellij.psi.PsiDocumentManager;
|
|
||||||
import com.intellij.testFramework.PsiTestUtil;
|
|
||||||
import com.sun.jdi.Location;
|
import com.sun.jdi.Location;
|
||||||
import com.sun.jdi.ReferenceType;
|
import com.sun.jdi.ReferenceType;
|
||||||
import kotlin.KotlinPackage;
|
import kotlin.SequencesKt;
|
||||||
|
import kotlin.StringsKt;
|
||||||
|
import kotlin.Unit;
|
||||||
|
import kotlin.io.FilesKt;
|
||||||
|
import kotlin.jvm.functions.Function1;
|
||||||
import org.jetbrains.annotations.NotNull;
|
import org.jetbrains.annotations.NotNull;
|
||||||
import org.jetbrains.kotlin.backend.common.output.OutputFile;
|
import org.jetbrains.kotlin.backend.common.output.OutputFile;
|
||||||
import org.jetbrains.kotlin.backend.common.output.OutputFileCollection;
|
import org.jetbrains.kotlin.backend.common.output.OutputFileCollection;
|
||||||
import org.jetbrains.kotlin.codegen.GenerationUtils;
|
import org.jetbrains.kotlin.codegen.GenerationUtils;
|
||||||
import org.jetbrains.kotlin.codegen.state.GenerationState;
|
import org.jetbrains.kotlin.codegen.state.GenerationState;
|
||||||
import org.jetbrains.kotlin.idea.test.KotlinMultiFileTestCase;
|
|
||||||
import org.jetbrains.kotlin.idea.test.PluginTestCaseBase;
|
|
||||||
import org.jetbrains.kotlin.idea.project.PluginJetFilesProvider;
|
import org.jetbrains.kotlin.idea.project.PluginJetFilesProvider;
|
||||||
|
import org.jetbrains.kotlin.idea.test.JetLightCodeInsightFixtureTestCase;
|
||||||
|
import org.jetbrains.kotlin.idea.test.JetWithJdkAndRuntimeLightProjectDescriptor;
|
||||||
|
import org.jetbrains.kotlin.idea.test.PluginTestCaseBase;
|
||||||
import org.jetbrains.kotlin.psi.JetFile;
|
import org.jetbrains.kotlin.psi.JetFile;
|
||||||
import org.jetbrains.kotlin.utils.UtilsPackage;
|
import org.jetbrains.kotlin.utils.UtilsPackage;
|
||||||
|
|
||||||
|
import java.io.File;
|
||||||
import java.util.ArrayList;
|
import java.util.ArrayList;
|
||||||
import java.util.Collection;
|
import java.util.Collection;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
@@ -52,7 +56,7 @@ import java.util.Map;
|
|||||||
import java.util.regex.Matcher;
|
import java.util.regex.Matcher;
|
||||||
import java.util.regex.Pattern;
|
import java.util.regex.Pattern;
|
||||||
|
|
||||||
public abstract class AbstractJetPositionManagerTest extends KotlinMultiFileTestCase {
|
public abstract class AbstractJetPositionManagerTest extends JetLightCodeInsightFixtureTestCase {
|
||||||
// Breakpoint is given as a line comment on a specific line, containing the regexp to match the name of the class where that line
|
// Breakpoint is given as a line comment on a specific line, containing the regexp to match the name of the class where that line
|
||||||
// can be found. This pattern matches against these line comments and saves the class name in the first group
|
// can be found. This pattern matches against these line comments and saves the class name in the first group
|
||||||
private static final Pattern BREAKPOINT_PATTERN = Pattern.compile("^.*//\\s*(.+)\\s*$");
|
private static final Pattern BREAKPOINT_PATTERN = Pattern.compile("^.*//\\s*(.+)\\s*$");
|
||||||
@@ -60,15 +64,21 @@ public abstract class AbstractJetPositionManagerTest extends KotlinMultiFileTest
|
|||||||
@NotNull
|
@NotNull
|
||||||
@Override
|
@Override
|
||||||
protected String getTestDataPath() {
|
protected String getTestDataPath() {
|
||||||
return PluginTestCaseBase.getTestDataPathBase();
|
return PluginTestCaseBase.getTestDataPathBase() + "/debugger/positionManager/";
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void setUp() {
|
||||||
|
super.setUp();
|
||||||
|
myFixture.setTestDataPath(PluginTestCaseBase.getTestDataPathBase());
|
||||||
}
|
}
|
||||||
|
|
||||||
private DebugProcessImpl debugProcess;
|
private DebugProcessImpl debugProcess;
|
||||||
|
|
||||||
@NotNull
|
@NotNull
|
||||||
@Override
|
@Override
|
||||||
protected String getTestRoot() {
|
protected LightProjectDescriptor getProjectDescriptor() {
|
||||||
return "/debugger/positionManager/";
|
return JetWithJdkAndRuntimeLightProjectDescriptor.INSTANCE;
|
||||||
}
|
}
|
||||||
|
|
||||||
@NotNull
|
@NotNull
|
||||||
@@ -89,18 +99,30 @@ public abstract class AbstractJetPositionManagerTest extends KotlinMultiFileTest
|
|||||||
|
|
||||||
protected void doTest(@NotNull String fileName) throws Exception {
|
protected void doTest(@NotNull String fileName) throws Exception {
|
||||||
if (fileName.endsWith(".kt")) {
|
if (fileName.endsWith(".kt")) {
|
||||||
String path = KotlinPackage.substringAfter(fileName, PluginTestCaseBase.TEST_DATA_PROJECT_RELATIVE.substring(1), fileName);
|
String path = getPath(fileName);
|
||||||
configureByFile(path);
|
myFixture.configureByFile(path);
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
VirtualFile rootDir = PsiTestUtil.createTestProjectStructure(myProject, myModule, fileName, myFilesToDelete, false);
|
String path = getPath(fileName);
|
||||||
prepareProject(rootDir);
|
SequencesKt.forEach(FilesKt.walkTopDown(new File(path)), new Function1<File, Unit>() {
|
||||||
PsiDocumentManager.getInstance(myProject).commitAllDocuments();
|
@Override
|
||||||
|
public Unit invoke(File file) {
|
||||||
|
String fileName = file.getName();
|
||||||
|
String path = getPath(fileName);
|
||||||
|
myFixture.configureByFile(path);
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
performTest();
|
performTest();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@NotNull
|
||||||
|
private static String getPath(@NotNull String fileName) {
|
||||||
|
return StringsKt.substringAfter(fileName, PluginTestCaseBase.TEST_DATA_PROJECT_RELATIVE.substring(1), fileName);
|
||||||
|
}
|
||||||
|
|
||||||
private void performTest() {
|
private void performTest() {
|
||||||
Project project = getProject();
|
Project project = getProject();
|
||||||
List<JetFile> files = new ArrayList<JetFile>(PluginJetFilesProvider.allFilesInProject(project));
|
List<JetFile> files = new ArrayList<JetFile>(PluginJetFilesProvider.allFilesInProject(project));
|
||||||
|
|||||||
@@ -91,6 +91,12 @@ public class JetPositionManagerTestGenerated extends AbstractJetPositionManagerT
|
|||||||
doTest(fileName);
|
doTest(fileName);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@TestMetadata("JvmNameAnnotation.kt")
|
||||||
|
public void testJvmNameAnnotation() throws Exception {
|
||||||
|
String fileName = JetTestUtils.navigationMetadata("idea/testData/debugger/positionManager/JvmNameAnnotation.kt");
|
||||||
|
doTest(fileName);
|
||||||
|
}
|
||||||
|
|
||||||
@TestMetadata("localFunction.kt")
|
@TestMetadata("localFunction.kt")
|
||||||
public void testLocalFunction() throws Exception {
|
public void testLocalFunction() throws Exception {
|
||||||
String fileName = JetTestUtils.navigationMetadata("idea/testData/debugger/positionManager/localFunction.kt");
|
String fileName = JetTestUtils.navigationMetadata("idea/testData/debugger/positionManager/localFunction.kt");
|
||||||
|
|||||||
Reference in New Issue
Block a user