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.descriptors.ClassDescriptor
|
||||
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.analyzeFullyAndGetResult
|
||||
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.application.runReadAction
|
||||
import org.jetbrains.kotlin.load.kotlin.PackageClassUtils
|
||||
import org.jetbrains.kotlin.load.kotlin.PackagePartClassUtils
|
||||
import org.jetbrains.kotlin.name.FqName
|
||||
import org.jetbrains.kotlin.psi.*
|
||||
import org.jetbrains.kotlin.psi.psiUtil.getElementTextWithContext
|
||||
import org.jetbrains.kotlin.resolve.BindingContext
|
||||
import org.jetbrains.kotlin.resolve.inline.InlineUtil
|
||||
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 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) {
|
||||
return SourcePosition.createFromLine(defaultPsiFile, 0)
|
||||
}
|
||||
@@ -178,7 +178,7 @@ public class JetPositionManager(private val myDebugProcess: DebugProcess) : Mult
|
||||
|
||||
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 {
|
||||
@@ -375,19 +375,7 @@ public class JetPositionManager(private val myDebugProcess: DebugProcess) : Mult
|
||||
}
|
||||
}
|
||||
|
||||
if (isInLibrary) {
|
||||
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)
|
||||
return PositionedElement(NoResolveFileClassesProvider.getFileClassInternalName(file), element)
|
||||
}
|
||||
|
||||
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)
|
||||
}
|
||||
|
||||
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> {
|
||||
|
||||
-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('.', '/');
|
||||
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;
|
||||
VirtualFile virtualFile = file.getVirtualFile();
|
||||
|
||||
@@ -22,11 +22,9 @@ 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.roots.libraries.LibraryUtil;
|
||||
import com.intellij.openapi.util.io.FileUtilRt;
|
||||
import com.intellij.psi.PsiElement;
|
||||
import com.intellij.psi.search.GlobalSearchScope;
|
||||
import com.intellij.psi.util.PsiTreeUtil;
|
||||
import kotlin.KotlinPackage;
|
||||
import kotlin.Pair;
|
||||
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.FunctionDescriptor;
|
||||
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.debugger.DebuggerPackage;
|
||||
import org.jetbrains.kotlin.idea.resolve.ResolutionFacade;
|
||||
import org.jetbrains.kotlin.idea.stubindex.StaticFacadeIndexUtil;
|
||||
import org.jetbrains.kotlin.load.kotlin.PackageClassUtils;
|
||||
import org.jetbrains.kotlin.load.kotlin.PackagePartClassUtils;
|
||||
import org.jetbrains.kotlin.name.FqName;
|
||||
import org.jetbrains.kotlin.psi.*;
|
||||
import org.jetbrains.kotlin.resolve.BindingContext;
|
||||
@@ -66,9 +61,8 @@ public class DebuggerUtils {
|
||||
public static JetFile findSourceFileForClass(
|
||||
@NotNull Project project,
|
||||
@NotNull GlobalSearchScope searchScope,
|
||||
@NotNull final JvmClassName className,
|
||||
@NotNull final String fileName,
|
||||
final int lineNumber
|
||||
@NotNull JvmClassName className,
|
||||
@NotNull final String fileName
|
||||
) {
|
||||
String extension = FileUtilRt.getExtension(fileName);
|
||||
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();
|
||||
}
|
||||
|
||||
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) {
|
||||
String packageName = PackageClassUtils.getPackageClassInternalName(className.getPackageFqName());
|
||||
|
||||
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
|
||||
public static Pair<BindingContext, List<JetFile>> analyzeInlinedFunctions(
|
||||
@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.project.Project;
|
||||
import com.intellij.openapi.util.text.StringUtil;
|
||||
import com.intellij.openapi.vfs.VirtualFile;
|
||||
import com.intellij.psi.PsiDocumentManager;
|
||||
import com.intellij.testFramework.PsiTestUtil;
|
||||
import com.intellij.testFramework.LightProjectDescriptor;
|
||||
import com.sun.jdi.Location;
|
||||
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.kotlin.backend.common.output.OutputFile;
|
||||
import org.jetbrains.kotlin.backend.common.output.OutputFileCollection;
|
||||
import org.jetbrains.kotlin.codegen.GenerationUtils;
|
||||
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.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.utils.UtilsPackage;
|
||||
|
||||
import java.io.File;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Collection;
|
||||
import java.util.List;
|
||||
@@ -52,7 +56,7 @@ import java.util.Map;
|
||||
import java.util.regex.Matcher;
|
||||
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
|
||||
// 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*$");
|
||||
@@ -60,15 +64,21 @@ public abstract class AbstractJetPositionManagerTest extends KotlinMultiFileTest
|
||||
@NotNull
|
||||
@Override
|
||||
protected String getTestDataPath() {
|
||||
return PluginTestCaseBase.getTestDataPathBase();
|
||||
return PluginTestCaseBase.getTestDataPathBase() + "/debugger/positionManager/";
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setUp() {
|
||||
super.setUp();
|
||||
myFixture.setTestDataPath(PluginTestCaseBase.getTestDataPathBase());
|
||||
}
|
||||
|
||||
private DebugProcessImpl debugProcess;
|
||||
|
||||
@NotNull
|
||||
@Override
|
||||
protected String getTestRoot() {
|
||||
return "/debugger/positionManager/";
|
||||
protected LightProjectDescriptor getProjectDescriptor() {
|
||||
return JetWithJdkAndRuntimeLightProjectDescriptor.INSTANCE;
|
||||
}
|
||||
|
||||
@NotNull
|
||||
@@ -89,18 +99,30 @@ public abstract class AbstractJetPositionManagerTest extends KotlinMultiFileTest
|
||||
|
||||
protected void doTest(@NotNull String fileName) throws Exception {
|
||||
if (fileName.endsWith(".kt")) {
|
||||
String path = KotlinPackage.substringAfter(fileName, PluginTestCaseBase.TEST_DATA_PROJECT_RELATIVE.substring(1), fileName);
|
||||
configureByFile(path);
|
||||
String path = getPath(fileName);
|
||||
myFixture.configureByFile(path);
|
||||
}
|
||||
else {
|
||||
VirtualFile rootDir = PsiTestUtil.createTestProjectStructure(myProject, myModule, fileName, myFilesToDelete, false);
|
||||
prepareProject(rootDir);
|
||||
PsiDocumentManager.getInstance(myProject).commitAllDocuments();
|
||||
String path = getPath(fileName);
|
||||
SequencesKt.forEach(FilesKt.walkTopDown(new File(path)), new Function1<File, Unit>() {
|
||||
@Override
|
||||
public Unit invoke(File file) {
|
||||
String fileName = file.getName();
|
||||
String path = getPath(fileName);
|
||||
myFixture.configureByFile(path);
|
||||
return null;
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
performTest();
|
||||
}
|
||||
|
||||
@NotNull
|
||||
private static String getPath(@NotNull String fileName) {
|
||||
return StringsKt.substringAfter(fileName, PluginTestCaseBase.TEST_DATA_PROJECT_RELATIVE.substring(1), fileName);
|
||||
}
|
||||
|
||||
private void performTest() {
|
||||
Project project = getProject();
|
||||
List<JetFile> files = new ArrayList<JetFile>(PluginJetFilesProvider.allFilesInProject(project));
|
||||
|
||||
@@ -91,6 +91,12 @@ public class JetPositionManagerTestGenerated extends AbstractJetPositionManagerT
|
||||
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")
|
||||
public void testLocalFunction() throws Exception {
|
||||
String fileName = JetTestUtils.navigationMetadata("idea/testData/debugger/positionManager/localFunction.kt");
|
||||
|
||||
Reference in New Issue
Block a user