Debugger: fix className for properties in class objects
This commit is contained in:
@@ -39,11 +39,11 @@ import org.jetbrains.annotations.NotNull;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
import org.jetbrains.annotations.TestOnly;
|
||||
import org.jetbrains.jet.analyzer.AnalyzeExhaust;
|
||||
import org.jetbrains.jet.codegen.AsmUtil;
|
||||
import org.jetbrains.jet.codegen.ClassBuilderFactories;
|
||||
import org.jetbrains.jet.codegen.state.GenerationState;
|
||||
import org.jetbrains.jet.codegen.state.JetTypeMapper;
|
||||
import org.jetbrains.jet.lang.descriptors.ClassDescriptor;
|
||||
import org.jetbrains.jet.lang.descriptors.ValueParameterDescriptor;
|
||||
import org.jetbrains.jet.lang.descriptors.*;
|
||||
import org.jetbrains.jet.lang.psi.*;
|
||||
import org.jetbrains.jet.lang.resolve.BindingContext;
|
||||
import org.jetbrains.jet.lang.resolve.calls.callUtil.CallUtilPackage;
|
||||
@@ -208,6 +208,29 @@ public class JetPositionManager implements PositionManager {
|
||||
return asmType.getInternalName();
|
||||
}
|
||||
}
|
||||
else if (element instanceof JetClassInitializer) {
|
||||
PsiElement parent = getElementToCalculateClassName(element.getParent());
|
||||
// Class-object initializer
|
||||
if (parent instanceof JetObjectDeclaration && ((JetObjectDeclaration) parent).isClassObject()) {
|
||||
return getClassNameForElement(parent.getParent(), typeMapper, file, isInLibrary);
|
||||
}
|
||||
return getClassNameForElement(element, typeMapper, file, isInLibrary);
|
||||
}
|
||||
else if (element instanceof JetProperty && (!((JetProperty) element).isTopLevel() || !isInLibrary)) {
|
||||
if (isInPropertyAccessor(notPositionedElement)) {
|
||||
JetClassOrObject classOrObject = PsiTreeUtil.getParentOfType(element, JetClassOrObject.class);
|
||||
if (classOrObject != null) {
|
||||
return getJvmInternalNameForImpl(typeMapper, classOrObject);
|
||||
}
|
||||
}
|
||||
|
||||
VariableDescriptor descriptor = (VariableDescriptor) typeMapper.getBindingContext().get(BindingContext.DECLARATION_TO_DESCRIPTOR, element);
|
||||
if (!(descriptor instanceof PropertyDescriptor)) {
|
||||
return getClassNameForElement(element.getParent(), typeMapper, file, isInLibrary);
|
||||
}
|
||||
|
||||
return getJvmInternalNameForPropertyOwner(typeMapper, (PropertyDescriptor) descriptor);
|
||||
}
|
||||
else if (element instanceof JetNamedFunction) {
|
||||
PsiElement parent = getElementToCalculateClassName(element);
|
||||
if (parent instanceof JetClassOrObject) {
|
||||
@@ -230,14 +253,31 @@ public class JetPositionManager implements PositionManager {
|
||||
}
|
||||
|
||||
@Nullable
|
||||
private static JetNamedDeclaration getElementToCalculateClassName(@Nullable PsiElement notPositionedElement) {
|
||||
private static JetDeclaration getElementToCalculateClassName(@Nullable PsiElement notPositionedElement) {
|
||||
//noinspection unchecked
|
||||
return PsiTreeUtil.getParentOfType(notPositionedElement, JetClassOrObject.class, JetFunctionLiteral.class, JetNamedFunction.class);
|
||||
return PsiTreeUtil.getParentOfType(notPositionedElement,
|
||||
JetClassOrObject.class,
|
||||
JetFunctionLiteral.class, JetNamedFunction.class,
|
||||
JetProperty.class,
|
||||
JetClassInitializer.class);
|
||||
}
|
||||
|
||||
@NotNull
|
||||
public static String getJvmInternalNameForPropertyOwner(@NotNull JetTypeMapper typeMapper, @NotNull PropertyDescriptor descriptor) {
|
||||
return typeMapper.mapOwner(
|
||||
AsmUtil.isPropertyWithBackingFieldInOuterClass(descriptor) ? descriptor.getContainingDeclaration() : descriptor,
|
||||
true)
|
||||
.getInternalName();
|
||||
}
|
||||
|
||||
private static boolean isInPropertyAccessor(@Nullable PsiElement element) {
|
||||
//noinspection unchecked
|
||||
return element instanceof JetPropertyAccessor || ((JetElement) PsiTreeUtil.getParentOfType(element, JetProperty.class, JetPropertyAccessor.class)) instanceof JetPropertyAccessor;
|
||||
}
|
||||
|
||||
@Nullable
|
||||
private static JetElement getElementToCreateTypeMapperForLibraryFile(@Nullable PsiElement notPositionedElement) {
|
||||
return PsiTreeUtil.getParentOfType(notPositionedElement, JetElement.class);
|
||||
private static JetElement getElementToCreateTypeMapperForLibraryFile(@Nullable PsiElement element) {
|
||||
return element instanceof JetElement ? (JetElement) element : PsiTreeUtil.getParentOfType(element, JetElement.class);
|
||||
}
|
||||
|
||||
@Nullable
|
||||
|
||||
@@ -1,7 +1,43 @@
|
||||
class A {
|
||||
class object {
|
||||
fun foo() {
|
||||
|
||||
{
|
||||
1 + 1 // A
|
||||
val a = 1 // A
|
||||
fun foo() {
|
||||
1 // A\$object\$1
|
||||
}
|
||||
}
|
||||
|
||||
val prop = 1 // A
|
||||
|
||||
val prop2: Int
|
||||
get() {
|
||||
val a = 1 + 1 // A\$object
|
||||
return 1 // A\$object
|
||||
}
|
||||
|
||||
val prop3: Int
|
||||
get() = 1 // A\$object
|
||||
|
||||
fun foo() = 1 // A\$object
|
||||
|
||||
fun foo2() {
|
||||
"" // A\$object
|
||||
|
||||
val o = object {
|
||||
val p = 1 // A\$object\$foo2\$o\$1
|
||||
val p2: Int
|
||||
get() {
|
||||
return 1 // A\$object\$foo2\$o\$1
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
trait T {
|
||||
class object {
|
||||
val prop = 1 // T\$object
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
package customLib.simpleLibFile
|
||||
|
||||
public fun foo() {
|
||||
val a = 1
|
||||
1 + 1
|
||||
}
|
||||
|
||||
@@ -21,8 +21,8 @@ inline fun foo(f: () -> Unit) {
|
||||
|
||||
// EXPRESSION: var1
|
||||
// RESULT: 1: I
|
||||
frame = main():7, FrameSharedVarLocalVarPackage-@packagePartHASH {frameSharedVarLocalVar}
|
||||
static = static = frameSharedVarLocalVar.FrameSharedVarLocalVarPackage-@packagePartHASH
|
||||
frame = main():7, FrameSharedVarLocalVarPackage$@packagePartHASH {frameSharedVarLocalVar}
|
||||
static = static = frameSharedVarLocalVar.FrameSharedVarLocalVarPackage$@packagePartHASH
|
||||
local = args: java.lang.String[] = {java.lang.String[0]@uniqueID}
|
||||
local = var1: kotlin.jvm.internal.Ref$IntRef = {kotlin.jvm.internal.Ref$IntRef@uniqueID}1
|
||||
field = element: int = 1
|
||||
|
||||
@@ -23,6 +23,7 @@ import com.intellij.debugger.PositionManager;
|
||||
import com.intellij.debugger.SourcePosition;
|
||||
import com.intellij.debugger.engine.DebugProcess;
|
||||
import com.intellij.debugger.engine.DebugProcessEvents;
|
||||
import com.intellij.debugger.engine.DebugProcessImpl;
|
||||
import com.intellij.debugger.jdi.VirtualMachineProxyImpl;
|
||||
import com.intellij.openapi.application.ApplicationManager;
|
||||
import com.intellij.openapi.project.Project;
|
||||
@@ -62,6 +63,8 @@ public abstract class AbstractJetPositionManagerTest extends MultiFileTestCase {
|
||||
return PluginTestCaseBase.getTestDataPathBase();
|
||||
}
|
||||
|
||||
private DebugProcessImpl debugProcess;
|
||||
|
||||
@NotNull
|
||||
@Override
|
||||
protected String getTestRoot() {
|
||||
@@ -111,7 +114,7 @@ public abstract class AbstractJetPositionManagerTest extends MultiFileTestCase {
|
||||
|
||||
Map<String, ReferenceType> referencesByName = getReferenceMap(state.getFactory());
|
||||
|
||||
DebugProcess debugProcess = createDebugProcess(referencesByName);
|
||||
debugProcess = createDebugProcess(referencesByName);
|
||||
|
||||
final PositionManager positionManager = createPositionManager(debugProcess, files, state);
|
||||
|
||||
@@ -128,6 +131,15 @@ public abstract class AbstractJetPositionManagerTest extends MultiFileTestCase {
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
public void tearDown() throws Exception {
|
||||
if (debugProcess != null) {
|
||||
debugProcess.dispose();
|
||||
}
|
||||
super.tearDown();
|
||||
}
|
||||
|
||||
private static Collection<Breakpoint> extractBreakpointsInfo(JetFile file, String fileContent) {
|
||||
@@ -175,7 +187,7 @@ public abstract class AbstractJetPositionManagerTest extends MultiFileTestCase {
|
||||
assertNotNull(classes);
|
||||
assertEquals(1, classes.size());
|
||||
ReferenceType type = classes.get(0);
|
||||
assertTrue("Type name " + type.name() + " doesn't match " + breakpoint.classNameRegexp,
|
||||
assertTrue("Type name " + type.name() + " doesn't match " + breakpoint.classNameRegexp + " for line " + (breakpoint.lineNumber + 1),
|
||||
type.name().matches(breakpoint.classNameRegexp));
|
||||
|
||||
// JDI names are of form "package.Class$InnerClass"
|
||||
|
||||
Reference in New Issue
Block a user