From 0a97481184c42886db54beef2843d441a9ccc2cd Mon Sep 17 00:00:00 2001 From: Natalia Ukhorskaya Date: Tue, 11 Nov 2014 15:59:04 +0300 Subject: [PATCH] Mark lineNumbers for synthetic accessors --- .../jet/codegen/FunctionCodegen.java | 12 ++------ .../codegen/ImplementationBodyCodegen.java | 22 ++++++++++++++ .../extractFunctionForDebuggerUtil.kt | 15 +++++++--- .../debugger/tinyApp/outs/accessors.out | 20 +++++++++++++ .../src/stepInto/stepInto/accessors.kt | 30 +++++++++++++++++++ .../debugger/KotlinSteppingTestGenerated.java | 6 ++++ 6 files changed, 91 insertions(+), 14 deletions(-) create mode 100644 idea/testData/debugger/tinyApp/outs/accessors.out create mode 100644 idea/testData/debugger/tinyApp/src/stepInto/stepInto/accessors.kt diff --git a/compiler/backend/src/org/jetbrains/jet/codegen/FunctionCodegen.java b/compiler/backend/src/org/jetbrains/jet/codegen/FunctionCodegen.java index 44570458148..927153c5a41 100644 --- a/compiler/backend/src/org/jetbrains/jet/codegen/FunctionCodegen.java +++ b/compiler/backend/src/org/jetbrains/jet/codegen/FunctionCodegen.java @@ -782,20 +782,12 @@ public class FunctionCodegen extends ParentCodegenAware { mv.visitCode(); - PsiElement classElement = classDescriptorToDeclaration(owner.getThisDescriptor()); - if (classElement != null) { - Integer lineNumber = CodegenUtil.getLineNumberForElement(classElement, false); - if (lineNumber != null) { - Label label = new Label(); - mv.visitLabel(label); - mv.visitLineNumber(lineNumber, label); - } - } - Type[] argTypes = bridge.getArgumentTypes(); Type[] originalArgTypes = delegateTo.getArgumentTypes(); InstructionAdapter iv = new InstructionAdapter(mv); + ImplementationBodyCodegen.markLineNumberForSyntheticFunction(owner.getThisDescriptor(), iv); + iv.load(0, OBJECT_TYPE); for (int i = 0, reg = 1; i < argTypes.length; i++) { StackValue.local(reg, argTypes[i]).put(originalArgTypes[i], iv); diff --git a/compiler/backend/src/org/jetbrains/jet/codegen/ImplementationBodyCodegen.java b/compiler/backend/src/org/jetbrains/jet/codegen/ImplementationBodyCodegen.java index a266b846fd6..a39be939dcc 100644 --- a/compiler/backend/src/org/jetbrains/jet/codegen/ImplementationBodyCodegen.java +++ b/compiler/backend/src/org/jetbrains/jet/codegen/ImplementationBodyCodegen.java @@ -71,6 +71,7 @@ import static org.jetbrains.jet.codegen.AsmUtil.*; import static org.jetbrains.jet.codegen.JvmCodegenUtil.*; import static org.jetbrains.jet.codegen.binding.CodegenBinding.*; import static org.jetbrains.jet.descriptors.serialization.NameSerializationUtil.createNameResolver; +import static org.jetbrains.jet.lang.resolve.DescriptorToSourceUtils.classDescriptorToDeclaration; import static org.jetbrains.jet.lang.resolve.DescriptorToSourceUtils.descriptorToDeclaration; import static org.jetbrains.jet.lang.resolve.DescriptorUtils.*; import static org.jetbrains.jet.lang.resolve.java.AsmTypeConstants.*; @@ -875,6 +876,8 @@ public class ImplementationBodyCodegen extends ClassBodyCodegen { new FunctionGenerationStrategy.CodegenBased(state, bridge) { @Override public void doGenerateBody(@NotNull ExpressionCodegen codegen, @NotNull JvmMethodSignature signature) { + markLineNumberForSyntheticFunction(descriptor, codegen.v); + generateMethodCallTo(original, codegen.v); codegen.v.areturn(signature.getReturnType()); } @@ -897,6 +900,9 @@ public class ImplementationBodyCodegen extends ClassBodyCodegen { StackValue property = codegen.intermediateValueForProperty(original, forceField, null, MethodKind.SYNTHETIC_ACCESSOR); InstructionAdapter iv = codegen.v; + + markLineNumberForSyntheticFunction(descriptor, iv); + Type[] argTypes = signature.getAsmMethod().getArgumentTypes(); for (int i = 0, reg = 0; i < argTypes.length; i++) { Type argType = argTypes[i]; @@ -939,6 +945,22 @@ public class ImplementationBodyCodegen extends ClassBodyCodegen { } } + public static void markLineNumberForSyntheticFunction(@Nullable ClassDescriptor declarationDescriptor, @NotNull InstructionAdapter v) { + if (declarationDescriptor == null) { + return; + } + + PsiElement classElement = classDescriptorToDeclaration(declarationDescriptor); + if (classElement != null) { + Integer lineNumber = CodegenUtil.getLineNumberForElement(classElement, false); + if (lineNumber != null) { + Label label = new Label(); + v.visitLabel(label); + v.visitLineNumber(lineNumber, label); + } + } + } + private void generateMethodCallTo(FunctionDescriptor functionDescriptor, InstructionAdapter iv) { boolean isConstructor = functionDescriptor instanceof ConstructorDescriptor; boolean callFromAccessor = !JetTypeMapper.isAccessor(functionDescriptor); diff --git a/idea/src/org/jetbrains/jet/plugin/debugger/evaluate/extractFunctionForDebuggerUtil.kt b/idea/src/org/jetbrains/jet/plugin/debugger/evaluate/extractFunctionForDebuggerUtil.kt index e490fa12f1a..6824f1f7b64 100644 --- a/idea/src/org/jetbrains/jet/plugin/debugger/evaluate/extractFunctionForDebuggerUtil.kt +++ b/idea/src/org/jetbrains/jet/plugin/debugger/evaluate/extractFunctionForDebuggerUtil.kt @@ -179,15 +179,22 @@ private fun getExpressionToAddDebugExpressionBefore(tmpFile: JetFile, contextEle private fun addDebugExpressionBeforeContextElement(codeFragment: JetCodeFragment, contextElement: PsiElement): JetExpression? { val psiFactory = JetPsiFactory(codeFragment) + fun insertNewInitializer(classBody: JetClassBody): PsiElement? { + val initializer = psiFactory.createAnonymousInitializer() + val newInitializer = (classBody.addAfter(initializer, classBody.getFirstChild()) as JetClassInitializer) + val block = newInitializer.getBody() as JetBlockExpression + return block.getLastChild() + } + val elementBefore = when { contextElement is JetProperty && !contextElement.isLocal() -> { wrapInRunFun(contextElement.getDelegateExpressionOrInitializer()!!) } contextElement is JetClass -> { - val initializer = psiFactory.createAnonymousInitializer() - val newInitializer = (contextElement.getBody().addAfter(initializer, contextElement.getBody().getFirstChild()) as JetClassInitializer) - val block = newInitializer.getBody() as JetBlockExpression - block.getLastChild() + insertNewInitializer(contextElement.getBody()) + } + contextElement is JetClassObject -> { + insertNewInitializer(contextElement.getObjectDeclaration().getBody()) } contextElement is JetFunctionLiteral -> { val block = contextElement.getBodyExpression()!! diff --git a/idea/testData/debugger/tinyApp/outs/accessors.out b/idea/testData/debugger/tinyApp/outs/accessors.out new file mode 100644 index 00000000000..0ea0df9a46f --- /dev/null +++ b/idea/testData/debugger/tinyApp/outs/accessors.out @@ -0,0 +1,20 @@ +LineBreakpoint created at accessors.kt:10 +!JDK_HOME!\bin\java -agentlib:jdwp=transport=dt_socket,address=!HOST_NAME!:!HOST_PORT!,suspend=y,server=n -Dfile.encoding=!FILE_ENCODING! -classpath !APP_PATH!\classes;!KOTLIN_RUNTIME!;!CUSTOM_LIBRARY!;!RT_JAR! accessors.AccessorsPackage +Connected to the target VM, address: '!HOST_NAME!:PORT_NAME!', transport: 'socket' +accessors.kt:10 +accessors.kt:17 +accessors.kt:18 +accessors.kt:15 +accessors.kt:11 +accessors.kt:22 +accessors.kt:15 +accessors.kt:11 +accessors.kt:12 +accessors.kt:25 +accessors.kt:26 +accessors.kt:15 +accessors.kt:13 +accessors.kt:5 +Disconnected from the target VM, address: '!HOST_NAME!:PORT_NAME!', transport: 'socket' + +Process finished with exit code 0 diff --git a/idea/testData/debugger/tinyApp/src/stepInto/stepInto/accessors.kt b/idea/testData/debugger/tinyApp/src/stepInto/stepInto/accessors.kt new file mode 100644 index 00000000000..20fce8c2b94 --- /dev/null +++ b/idea/testData/debugger/tinyApp/src/stepInto/stepInto/accessors.kt @@ -0,0 +1,30 @@ +package accessors + +fun main(args: Array) { + A().test() +} + +class A { + fun test() { + //Breakpoint! + foo() + prop + prop = 2 + } + + class object { + private fun foo() { + val a = 1 + } + + private var prop: Int = 2 + get() { + return 1 + } + set(i: Int) { + $prop = i + } + } +} + +// STEP_INTO: 13 \ No newline at end of file diff --git a/idea/tests/org/jetbrains/jet/plugin/debugger/KotlinSteppingTestGenerated.java b/idea/tests/org/jetbrains/jet/plugin/debugger/KotlinSteppingTestGenerated.java index 8f1b86a14ef..04ba974975c 100644 --- a/idea/tests/org/jetbrains/jet/plugin/debugger/KotlinSteppingTestGenerated.java +++ b/idea/tests/org/jetbrains/jet/plugin/debugger/KotlinSteppingTestGenerated.java @@ -209,6 +209,12 @@ public class KotlinSteppingTestGenerated extends AbstractKotlinSteppingTest { @TestDataPath("$PROJECT_ROOT") @RunWith(JUnit3RunnerWithInners.class) public static class StepIntoOnly extends AbstractKotlinSteppingTest { + @TestMetadata("accessors.kt") + public void testAccessors() throws Exception { + String fileName = JetTestUtils.navigationMetadata("idea/testData/debugger/tinyApp/src/stepInto/stepInto/accessors.kt"); + doStepIntoTest(fileName); + } + public void testAllFilesPresentInStepIntoOnly() throws Exception { JetTestUtils.assertAllTestsPresentByMetadata(this.getClass(), new File("idea/testData/debugger/tinyApp/src/stepInto/stepInto"), Pattern.compile("^(.+)\\.kt$"), true); }