Stepping: do not write line numbers for call arguments

#KT-3080 Fixed
This commit is contained in:
Natalia Ukhorskaya
2014-12-16 10:27:30 +03:00
parent c66af565f6
commit e35b960eb5
16 changed files with 219 additions and 17 deletions
@@ -19,13 +19,12 @@ package org.jetbrains.jet.backend.common;
import com.intellij.openapi.editor.Document;
import com.intellij.openapi.util.TextRange;
import com.intellij.psi.PsiElement;
import com.intellij.psi.PsiFile;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
import org.jetbrains.jet.codegen.bridges.BridgesPackage;
import org.jetbrains.jet.lang.descriptors.*;
import org.jetbrains.jet.lang.psi.JetDelegationSpecifier;
import org.jetbrains.jet.lang.psi.JetExpression;
import org.jetbrains.jet.lang.psi.JetSimpleNameExpression;
import org.jetbrains.jet.lang.psi.*;
import org.jetbrains.jet.lang.resolve.BindingContext;
import org.jetbrains.jet.lang.resolve.DescriptorUtils;
import org.jetbrains.jet.lang.resolve.calls.CallResolverUtil;
@@ -221,7 +220,13 @@ public class CodegenUtil {
@Nullable
public static Integer getLineNumberForElement(@NotNull PsiElement statement, boolean markEndOffset) {
Document document = statement.getContainingFile().getViewProvider().getDocument();
PsiFile file = statement.getContainingFile();
if (file instanceof JetFile) {
if (PsiPackage.getDoNotAnalyze((JetFile) file) != null) {
return null;
}
}
Document document = file.getViewProvider().getDocument();
TextRange textRange = statement.getTextRange();
return document != null ? document.getLineNumber(markEndOffset ? textRange.getEndOffset() : textRange.getStartOffset()) + 1 : null;
}
@@ -22,6 +22,7 @@ import org.jetbrains.jet.lang.psi.JetExpression;
import org.jetbrains.jet.lang.psi.ValueArgument;
import org.jetbrains.jet.lang.resolve.calls.model.DefaultValueArgument;
import org.jetbrains.jet.lang.resolve.calls.model.ExpressionValueArgument;
import org.jetbrains.jet.lang.resolve.calls.model.ResolvedValueArgument;
import org.jetbrains.jet.lang.resolve.calls.model.VarargValueArgument;
import org.jetbrains.org.objectweb.asm.Type;
@@ -50,6 +51,16 @@ public class CallBasedArgumentGenerator extends ArgumentGenerator {
"Value parameters and their types mismatch in sizes: " + valueParameters.size() + " != " + valueParameterTypes.size();
}
@NotNull
@Override
public List<Integer> generate(@NotNull List<ResolvedValueArgument> valueArguments) {
boolean shouldMarkLineNumbers = codegen.isShouldMarkLineNumbers();
codegen.setShouldMarkLineNumbers(false);
List<Integer> masks = super.generate(valueArguments);
codegen.setShouldMarkLineNumbers(shouldMarkLineNumbers);
return masks;
}
@Override
protected void generateExpression(int i, @NotNull ExpressionValueArgument argument) {
ValueParameterDescriptor parameter = valueParameters.get(i);
@@ -23,9 +23,9 @@ import org.jetbrains.jet.lang.descriptors.ValueParameterDescriptor;
import org.jetbrains.jet.lang.psi.JetExpression;
import org.jetbrains.jet.lang.resolve.calls.model.ResolvedCall;
public interface CallGenerator {
public abstract class CallGenerator {
class DefaultCallGenerator implements CallGenerator {
static class DefaultCallGenerator extends CallGenerator {
private final ExpressionCodegen codegen;
@@ -34,7 +34,7 @@ public interface CallGenerator {
}
@Override
public void genCall(
public void genCallInner(
@NotNull CallableMethod callableMethod,
ResolvedCall<?> resolvedCall,
boolean callDefault,
@@ -90,24 +90,35 @@ public interface CallGenerator {
}
}
void genCall(@NotNull CallableMethod callableMethod, @Nullable ResolvedCall<?> resolvedCall, boolean callDefault, @NotNull ExpressionCodegen codegen);
public void genCall(@NotNull CallableMethod callableMethod, @Nullable ResolvedCall<?> resolvedCall, boolean callDefault, @NotNull ExpressionCodegen codegen) {
if (resolvedCall != null) {
JetExpression calleeExpression = resolvedCall.getCall().getCalleeExpression();
if (calleeExpression != null) {
codegen.markStartLineNumber(calleeExpression);
}
}
void genCallWithoutAssertions(@NotNull CallableMethod callableMethod, @NotNull ExpressionCodegen codegen);
genCallInner(callableMethod, resolvedCall, callDefault, codegen);
}
void afterParameterPut(@NotNull Type type, StackValue stackValue, @NotNull ValueParameterDescriptor valueParameterDescriptor);
public abstract void genCallInner(@NotNull CallableMethod callableMethod, @Nullable ResolvedCall<?> resolvedCall, boolean callDefault, @NotNull ExpressionCodegen codegen);
void genValueAndPut(
public abstract void genCallWithoutAssertions(@NotNull CallableMethod callableMethod, @NotNull ExpressionCodegen codegen);
public abstract void afterParameterPut(@NotNull Type type, StackValue stackValue, @NotNull ValueParameterDescriptor valueParameterDescriptor);
public abstract void genValueAndPut(
@NotNull ValueParameterDescriptor valueParameterDescriptor,
@NotNull JetExpression argumentExpression,
@NotNull Type parameterType
);
void putValueIfNeeded(@Nullable ValueParameterDescriptor valueParameterDescriptor, @NotNull Type parameterType, @NotNull StackValue value);
public abstract void putValueIfNeeded(@Nullable ValueParameterDescriptor valueParameterDescriptor, @NotNull Type parameterType, @NotNull StackValue value);
void putCapturedValueOnStack(
public abstract void putCapturedValueOnStack(
@NotNull StackValue stackValue,
@NotNull Type valueType, int paramIndex
);
void putHiddenParams();
public abstract void putHiddenParams();
}
@@ -123,6 +123,7 @@ public class ExpressionCodegen extends JetVisitor<StackValue, StackValue> implem
public final Map<JetElement, StackValue> tempVariables = Maps.newHashMap();
private int myLastLineNumber = -1;
private boolean shouldMarkLineNumbers = true;
public ExpressionCodegen(
@NotNull MethodVisitor mv,
@@ -1636,11 +1637,21 @@ public class ExpressionCodegen extends JetVisitor<StackValue, StackValue> implem
});
}
public boolean isShouldMarkLineNumbers() {
return shouldMarkLineNumbers;
}
public void setShouldMarkLineNumbers(boolean shouldMarkLineNumbers) {
this.shouldMarkLineNumbers = shouldMarkLineNumbers;
}
public void markStartLineNumber(@NotNull JetElement element) {
markLineNumber(element, false);
}
public void markLineNumber(@NotNull JetElement statement, boolean markEndOffset) {
if (!shouldMarkLineNumbers) return;
Integer lineNumber = CodegenUtil.getLineNumberForElement(statement, markEndOffset);
if (lineNumber == null || lineNumber == myLastLineNumber) {
return;
@@ -57,7 +57,7 @@ import static org.jetbrains.jet.codegen.AsmUtil.getMethodAsmFlags;
import static org.jetbrains.jet.codegen.AsmUtil.isPrimitive;
import static org.jetbrains.jet.codegen.inline.InlineCodegenUtil.addInlineMarker;
public class InlineCodegen implements CallGenerator {
public class InlineCodegen extends CallGenerator {
private final GenerationState state;
private final JetTypeMapper typeMapper;
@@ -115,7 +115,7 @@ public class InlineCodegen implements CallGenerator {
}
@Override
public void genCall(@NotNull CallableMethod callableMethod, @Nullable ResolvedCall<?> resolvedCall, boolean callDefault, @NotNull ExpressionCodegen codegen) {
public void genCallInner(@NotNull CallableMethod callableMethod, @Nullable ResolvedCall<?> resolvedCall, boolean callDefault, @NotNull ExpressionCodegen codegen) {
MethodNode node = null;
try {
@@ -0,0 +1,17 @@
class A {
fun foo(a: A) = a
}
fun bar(a: A) = A()
fun foo() {
val a = A()
bar(
bar(
bar(a)
)
)
}
// 2 5 8 9 15
@@ -0,0 +1,15 @@
class A {
fun foo() = this
inline fun bar() = this
}
fun foo() {
val a = A()
a
.foo()
a
.bar()
}
// 2 3 7 8 9 11 12 13
@@ -0,0 +1,15 @@
class A {
fun foo() = this
inline fun bar() = this
}
fun foo() {
val a = A()
a.foo()
.foo()
a.bar()
.bar()
}
// 2 3 7 8 9 11 12 13
@@ -0,0 +1,12 @@
fun test() {
foo()
bar()
}
fun foo(i: Int = 1) {
}
inline fun bar(i: Int = 1) {
}
// 2 3 4 7 6 10 9
@@ -0,0 +1,16 @@
fun foo() {
foo({
val a = 1
})
foo() {
val a = 1
}
}
inline fun foo(f: () -> Unit) {
val a = 1
f()
}
// 2 3 6 7 9 12 13 14
@@ -0,0 +1,15 @@
fun foo() {
foo({
val a = 1
})
foo() {
val a = 1
}
}
fun foo(f: () -> Unit) {
f()
}
// 2 6 9 12 13 3 7
@@ -0,0 +1,10 @@
fun foo() {
foo(
1 + 1
)
}
fun foo(i: Int) {
}
// 2 5 8
@@ -0,0 +1,9 @@
fun foo() {
1 foo
1
}
fun Int.foo(i: Int) {
}
// 2 4 7
@@ -144,12 +144,48 @@ public class LineNumberTestGenerated extends AbstractLineNumberTest {
JetTestUtils.assertAllTestsPresentByMetadata(this.getClass(), new File("compiler/testData/lineNumber/custom"), Pattern.compile("^(.+)\\.kt$"), true);
}
@TestMetadata("callWithCallInArguments.kt")
public void testCallWithCallInArguments() throws Exception {
String fileName = JetTestUtils.navigationMetadata("compiler/testData/lineNumber/custom/callWithCallInArguments.kt");
doTestCustom(fileName);
}
@TestMetadata("callWithReceiver.kt")
public void testCallWithReceiver() throws Exception {
String fileName = JetTestUtils.navigationMetadata("compiler/testData/lineNumber/custom/callWithReceiver.kt");
doTestCustom(fileName);
}
@TestMetadata("chainCall.kt")
public void testChainCall() throws Exception {
String fileName = JetTestUtils.navigationMetadata("compiler/testData/lineNumber/custom/chainCall.kt");
doTestCustom(fileName);
}
@TestMetadata("compileTimeConstant.kt")
public void testCompileTimeConstant() throws Exception {
String fileName = JetTestUtils.navigationMetadata("compiler/testData/lineNumber/custom/compileTimeConstant.kt");
doTestCustom(fileName);
}
@TestMetadata("functionCallWithDefault.kt")
public void testFunctionCallWithDefault() throws Exception {
String fileName = JetTestUtils.navigationMetadata("compiler/testData/lineNumber/custom/functionCallWithDefault.kt");
doTestCustom(fileName);
}
@TestMetadata("functionCallWithInlinedLambdaParam.kt")
public void testFunctionCallWithInlinedLambdaParam() throws Exception {
String fileName = JetTestUtils.navigationMetadata("compiler/testData/lineNumber/custom/functionCallWithInlinedLambdaParam.kt");
doTestCustom(fileName);
}
@TestMetadata("functionCallWithLambdaParam.kt")
public void testFunctionCallWithLambdaParam() throws Exception {
String fileName = JetTestUtils.navigationMetadata("compiler/testData/lineNumber/custom/functionCallWithLambdaParam.kt");
doTestCustom(fileName);
}
@TestMetadata("ifThen.kt")
public void testIfThen() throws Exception {
String fileName = JetTestUtils.navigationMetadata("compiler/testData/lineNumber/custom/ifThen.kt");
@@ -162,6 +198,18 @@ public class LineNumberTestGenerated extends AbstractLineNumberTest {
doTestCustom(fileName);
}
@TestMetadata("multilineFunctionCall.kt")
public void testMultilineFunctionCall() throws Exception {
String fileName = JetTestUtils.navigationMetadata("compiler/testData/lineNumber/custom/multilineFunctionCall.kt");
doTestCustom(fileName);
}
@TestMetadata("multilineInfixCall.kt")
public void testMultilineInfixCall() throws Exception {
String fileName = JetTestUtils.navigationMetadata("compiler/testData/lineNumber/custom/multilineInfixCall.kt");
doTestCustom(fileName);
}
@TestMetadata("tryCatchExpression.kt")
public void testTryCatchExpression() throws Exception {
String fileName = JetTestUtils.navigationMetadata("compiler/testData/lineNumber/custom/tryCatchExpression.kt");
@@ -2,7 +2,9 @@ LineBreakpoint created at callableBug.kt:8
!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! callableBug.CallableBugPackage
Connected to the target VM, address: '!HOST_NAME!:PORT_NAME!', transport: 'socket'
callableBug.kt:8
callableBug.kt:8
Compile bytecode for callable
Compile bytecode for it
callableBug.kt:8
Disconnected from the target VM, address: '!HOST_NAME!:PORT_NAME!', transport: 'socket'
@@ -8,5 +8,10 @@ fun main(args: Array<String>) {
}.forEach { it + 2 }
}
// STEP_INTO: 1
// EXPRESSION: callable
// RESULT: 1: I
// RESULT: 1: I
// EXPRESSION: it
// RESULT: 2: I