multifile debugger tests
This commit is contained in:
@@ -16,6 +16,9 @@
|
|||||||
|
|
||||||
package org.jetbrains.jet.codegen;
|
package org.jetbrains.jet.codegen;
|
||||||
|
|
||||||
|
import com.google.common.base.Predicates;
|
||||||
|
import com.intellij.openapi.project.Project;
|
||||||
|
import com.intellij.psi.PsiFile;
|
||||||
import org.jetbrains.annotations.NotNull;
|
import org.jetbrains.annotations.NotNull;
|
||||||
import org.jetbrains.jet.analyzer.AnalyzeExhaust;
|
import org.jetbrains.jet.analyzer.AnalyzeExhaust;
|
||||||
import org.jetbrains.jet.lang.BuiltinsScopeExtensionMode;
|
import org.jetbrains.jet.lang.BuiltinsScopeExtensionMode;
|
||||||
@@ -24,6 +27,7 @@ import org.jetbrains.jet.lang.resolve.AnalyzerScriptParameter;
|
|||||||
import org.jetbrains.jet.lang.resolve.java.AnalyzerFacadeForJVM;
|
import org.jetbrains.jet.lang.resolve.java.AnalyzerFacadeForJVM;
|
||||||
|
|
||||||
import java.util.Collections;
|
import java.util.Collections;
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @author Stepan Koltsov
|
* @author Stepan Koltsov
|
||||||
@@ -33,17 +37,31 @@ public class GenerationUtils {
|
|||||||
private GenerationUtils() {
|
private GenerationUtils() {
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@NotNull
|
||||||
public static ClassFileFactory compileFileGetClassFileFactoryForTest(@NotNull JetFile psiFile) {
|
public static ClassFileFactory compileFileGetClassFileFactoryForTest(@NotNull JetFile psiFile) {
|
||||||
return compileFileGetGenerationStateForTest(psiFile).getFactory();
|
return compileFileGetGenerationStateForTest(psiFile).getFactory();
|
||||||
}
|
}
|
||||||
|
|
||||||
public static GenerationState compileFileGetGenerationStateForTest(JetFile psiFile) {
|
@NotNull
|
||||||
|
public static GenerationState compileFileGetGenerationStateForTest(@NotNull JetFile psiFile) {
|
||||||
final AnalyzeExhaust analyzeExhaust = AnalyzerFacadeForJVM.analyzeOneFileWithJavaIntegrationAndCheckForErrors(
|
final AnalyzeExhaust analyzeExhaust = AnalyzerFacadeForJVM.analyzeOneFileWithJavaIntegrationAndCheckForErrors(
|
||||||
psiFile, Collections.<AnalyzerScriptParameter>emptyList(), BuiltinsScopeExtensionMode.ALL);
|
psiFile, Collections.<AnalyzerScriptParameter>emptyList(), BuiltinsScopeExtensionMode.ALL);
|
||||||
|
return compileFilesGetGenerationState(analyzeExhaust, Collections.singletonList(psiFile));
|
||||||
|
}
|
||||||
|
|
||||||
|
@NotNull
|
||||||
|
public static GenerationState compileManyFilesGetGenerationStateForTest(@NotNull Project project, @NotNull List<JetFile> files) {
|
||||||
|
final AnalyzeExhaust analyzeExhaust = AnalyzerFacadeForJVM.analyzeFilesWithJavaIntegrationAndCheckForErrors(
|
||||||
|
project, files, Collections.<AnalyzerScriptParameter>emptyList(), Predicates.<PsiFile>alwaysTrue(), BuiltinsScopeExtensionMode.ALL);
|
||||||
|
return compileFilesGetGenerationState(analyzeExhaust, files);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@NotNull
|
||||||
|
private static GenerationState compileFilesGetGenerationState(@NotNull AnalyzeExhaust analyzeExhaust, @NotNull List<JetFile> files) {
|
||||||
analyzeExhaust.throwIfError();
|
analyzeExhaust.throwIfError();
|
||||||
GenerationState state = new GenerationState(ClassBuilderFactories.binaries(false), analyzeExhaust, Collections.singletonList(psiFile));
|
GenerationState state = new GenerationState(ClassBuilderFactories.binaries(false), analyzeExhaust, files);
|
||||||
state.compileCorrectFiles(CompilationErrorHandler.THROW_EXCEPTION);
|
state.compileCorrectFiles(CompilationErrorHandler.THROW_EXCEPTION);
|
||||||
return state;
|
return state;
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -35,6 +35,7 @@ import com.sun.jdi.ReferenceType;
|
|||||||
import com.sun.jdi.request.ClassPrepareRequest;
|
import com.sun.jdi.request.ClassPrepareRequest;
|
||||||
import org.jetbrains.annotations.NotNull;
|
import org.jetbrains.annotations.NotNull;
|
||||||
import org.jetbrains.annotations.Nullable;
|
import org.jetbrains.annotations.Nullable;
|
||||||
|
import org.jetbrains.annotations.TestOnly;
|
||||||
import org.jetbrains.jet.analyzer.AnalyzeExhaust;
|
import org.jetbrains.jet.analyzer.AnalyzeExhaust;
|
||||||
import org.jetbrains.jet.codegen.JetTypeMapper;
|
import org.jetbrains.jet.codegen.JetTypeMapper;
|
||||||
import org.jetbrains.jet.codegen.MapTypeMode;
|
import org.jetbrains.jet.codegen.MapTypeMode;
|
||||||
@@ -241,4 +242,16 @@ public class JetPositionManager implements PositionManager {
|
|||||||
}
|
}
|
||||||
return myDebugProcess.getRequestsManager().createClassPrepareRequest(classPrepareRequestor, className.replace('/', '.'));
|
return myDebugProcess.getRequestsManager().createClassPrepareRequest(classPrepareRequestor, className.replace('/', '.'));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@TestOnly
|
||||||
|
public void addTypeMapper(JetFile file, final JetTypeMapper typeMapper) {
|
||||||
|
FqName fqName = JetPsiUtil.getFQName(file);
|
||||||
|
CachedValue<JetTypeMapper> value = CachedValuesManager.getManager(file.getProject()).createCachedValue(new CachedValueProvider<JetTypeMapper>() {
|
||||||
|
@Override
|
||||||
|
public Result<JetTypeMapper> compute() {
|
||||||
|
return new Result<JetTypeMapper>(typeMapper, PsiModificationTracker.MODIFICATION_COUNT);
|
||||||
|
}
|
||||||
|
}, false);
|
||||||
|
myTypeMappers.put(fqName, value);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -0,0 +1,5 @@
|
|||||||
|
package test
|
||||||
|
|
||||||
|
fun foo() {
|
||||||
|
"" // test/namespace$src$a
|
||||||
|
}
|
||||||
@@ -0,0 +1,5 @@
|
|||||||
|
package test
|
||||||
|
|
||||||
|
fun bar() {
|
||||||
|
foo(); // test/namespace$src$b
|
||||||
|
}
|
||||||
@@ -16,21 +16,45 @@
|
|||||||
|
|
||||||
package org.jetbrains.jet.plugin.debugger;
|
package org.jetbrains.jet.plugin.debugger;
|
||||||
|
|
||||||
import com.intellij.debugger.PositionManagerFactory;
|
import com.intellij.debugger.engine.DebugProcess;
|
||||||
|
import org.jetbrains.annotations.NotNull;
|
||||||
|
import org.jetbrains.jet.codegen.GenerationState;
|
||||||
|
import org.jetbrains.jet.codegen.JetTypeMapper;
|
||||||
|
import org.jetbrains.jet.di.InjectorForJetTypeMapper;
|
||||||
|
import org.jetbrains.jet.lang.psi.JetFile;
|
||||||
import org.jetbrains.jet.plugin.PluginTestCaseBase;
|
import org.jetbrains.jet.plugin.PluginTestCaseBase;
|
||||||
|
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @author udalov
|
* @author udalov
|
||||||
*/
|
*/
|
||||||
public class JetPositionManagerTest extends PositionManagerTestCase {
|
public class JetPositionManagerTest extends PositionManagerTestCase {
|
||||||
|
private final JetPositionManagerFactory jetPositionManagerFactory = new JetPositionManagerFactory();
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
@NotNull
|
||||||
protected String getTestDataPath() {
|
protected String getTestDataPath() {
|
||||||
return PluginTestCaseBase.getTestDataPathBase() + "/debugger";
|
return PluginTestCaseBase.getTestDataPathBase() + "/debugger";
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
protected PositionManagerFactory getPositionManagerFactory() {
|
@NotNull
|
||||||
return new JetPositionManagerFactory();
|
protected JetPositionManager createPositionManager(DebugProcess process, List<JetFile> files, GenerationState state) {
|
||||||
|
JetPositionManager positionManager = (JetPositionManager) jetPositionManagerFactory.createPositionManager(process);
|
||||||
|
assertNotNull(positionManager);
|
||||||
|
|
||||||
|
JetTypeMapper typeMapper = new InjectorForJetTypeMapper(state.getBindingContext(), files).getJetTypeMapper();
|
||||||
|
typeMapper.getClosureAnnotator().init();
|
||||||
|
for (JetFile file : files) {
|
||||||
|
positionManager.addTypeMapper(file, typeMapper);
|
||||||
|
}
|
||||||
|
|
||||||
|
return positionManager;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void testMultiFileNamespace() {
|
||||||
|
doMultiTest("multiFileNamespace/a.kt", "multiFileNamespace/b.kt");
|
||||||
}
|
}
|
||||||
|
|
||||||
public void testAnnotation() {
|
public void testAnnotation() {
|
||||||
|
|||||||
@@ -16,10 +16,10 @@
|
|||||||
|
|
||||||
package org.jetbrains.jet.plugin.debugger;
|
package org.jetbrains.jet.plugin.debugger;
|
||||||
|
|
||||||
|
import com.google.common.collect.Lists;
|
||||||
import com.google.common.collect.Maps;
|
import com.google.common.collect.Maps;
|
||||||
import com.intellij.debugger.NoDataException;
|
import com.intellij.debugger.NoDataException;
|
||||||
import com.intellij.debugger.PositionManager;
|
import com.intellij.debugger.PositionManager;
|
||||||
import com.intellij.debugger.PositionManagerFactory;
|
|
||||||
import com.intellij.debugger.SourcePosition;
|
import com.intellij.debugger.SourcePosition;
|
||||||
import com.intellij.debugger.engine.DebugProcess;
|
import com.intellij.debugger.engine.DebugProcess;
|
||||||
import com.intellij.debugger.engine.DebugProcessEvents;
|
import com.intellij.debugger.engine.DebugProcessEvents;
|
||||||
@@ -27,11 +27,12 @@ import com.intellij.debugger.jdi.VirtualMachineProxyImpl;
|
|||||||
import com.intellij.openapi.application.ApplicationManager;
|
import com.intellij.openapi.application.ApplicationManager;
|
||||||
import com.intellij.openapi.util.io.FileUtil;
|
import com.intellij.openapi.util.io.FileUtil;
|
||||||
import com.intellij.openapi.util.text.StringUtil;
|
import com.intellij.openapi.util.text.StringUtil;
|
||||||
import com.intellij.psi.PsiFile;
|
|
||||||
import com.intellij.testFramework.PlatformTestCase;
|
import com.intellij.testFramework.PlatformTestCase;
|
||||||
import com.sun.jdi.*;
|
import com.sun.jdi.*;
|
||||||
|
import org.jetbrains.annotations.NotNull;
|
||||||
import org.jetbrains.jet.JetTestUtils;
|
import org.jetbrains.jet.JetTestUtils;
|
||||||
import org.jetbrains.jet.codegen.ClassFileFactory;
|
import org.jetbrains.jet.codegen.ClassFileFactory;
|
||||||
|
import org.jetbrains.jet.codegen.GenerationState;
|
||||||
import org.jetbrains.jet.codegen.GenerationUtils;
|
import org.jetbrains.jet.codegen.GenerationUtils;
|
||||||
import org.jetbrains.jet.lang.psi.JetFile;
|
import org.jetbrains.jet.lang.psi.JetFile;
|
||||||
import org.jetbrains.jet.utils.ExceptionUtils;
|
import org.jetbrains.jet.utils.ExceptionUtils;
|
||||||
@@ -52,9 +53,11 @@ public abstract class PositionManagerTestCase extends PlatformTestCase {
|
|||||||
// This pattern matches against these line comments and saves the class name in the first group
|
// This pattern matches against these line comments and saves the class name in the first group
|
||||||
private static final Pattern breakpointPattern = Pattern.compile("^.*//\\s*([a-zA-Z0-9._/$]*)\\s*$");
|
private static final Pattern breakpointPattern = Pattern.compile("^.*//\\s*([a-zA-Z0-9._/$]*)\\s*$");
|
||||||
|
|
||||||
|
@NotNull
|
||||||
protected abstract String getTestDataPath();
|
protected abstract String getTestDataPath();
|
||||||
|
|
||||||
protected abstract PositionManagerFactory getPositionManagerFactory();
|
@NotNull
|
||||||
|
protected abstract PositionManager createPositionManager(DebugProcess process, List<JetFile> files, GenerationState state);
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
protected final void setUp() throws Exception {
|
protected final void setUp() throws Exception {
|
||||||
@@ -92,31 +95,49 @@ public abstract class PositionManagerTestCase extends PlatformTestCase {
|
|||||||
}
|
}
|
||||||
|
|
||||||
protected void doTest() {
|
protected void doTest() {
|
||||||
File file = new File(getTestDataPath(), getTestName(true) + ".kt");
|
doTest(getTestDataPath() + "/" + getTestName(true) + ".kt");
|
||||||
String fileContent;
|
}
|
||||||
try {
|
|
||||||
fileContent = FileUtil.loadFile(file);
|
|
||||||
}
|
|
||||||
catch (IOException e) {
|
|
||||||
throw ExceptionUtils.rethrow(e);
|
|
||||||
}
|
|
||||||
final PsiFile psiFile = JetTestUtils.createFile(file.getAbsolutePath(), fileContent, getProject());
|
|
||||||
|
|
||||||
final Map<Integer, String> breakpoints = extractBreakpointsInfo(fileContent);
|
protected void doMultiTest(String... filenames) {
|
||||||
|
for (int i = 0; i < filenames.length; i++) {
|
||||||
|
filenames[i] = getTestDataPath() + "/" + filenames[i];
|
||||||
|
}
|
||||||
|
doTest(filenames);
|
||||||
|
}
|
||||||
|
|
||||||
Map<String, ReferenceType> referencesByName = compileFileGetReferenceMap((JetFile) psiFile);
|
private void doTest(String... filenames) {
|
||||||
|
final List<JetFile> files = Lists.newArrayList();
|
||||||
|
final List<Breakpoint> breakpoints = Lists.newArrayList();
|
||||||
|
|
||||||
|
for (String filename : filenames) {
|
||||||
|
File file = new File(filename);
|
||||||
|
String fileContent;
|
||||||
|
try {
|
||||||
|
fileContent = FileUtil.loadFile(file);
|
||||||
|
}
|
||||||
|
catch (IOException e) {
|
||||||
|
throw ExceptionUtils.rethrow(e);
|
||||||
|
}
|
||||||
|
final JetFile jetFile = (JetFile)JetTestUtils.createFile(file.getAbsolutePath(), fileContent, getProject());
|
||||||
|
|
||||||
|
files.add(jetFile);
|
||||||
|
breakpoints.addAll(extractBreakpointsInfo(jetFile, fileContent));
|
||||||
|
}
|
||||||
|
|
||||||
|
GenerationState state = GenerationUtils.compileManyFilesGetGenerationStateForTest(getProject(), files);
|
||||||
|
|
||||||
|
Map<String, ReferenceType> referencesByName = getReferenceMap(state.getFactory());
|
||||||
|
|
||||||
final DebugProcess debugProcess = createDebugProcess(referencesByName);
|
final DebugProcess debugProcess = createDebugProcess(referencesByName);
|
||||||
|
|
||||||
|
final PositionManager positionManager = createPositionManager(debugProcess, files, state);
|
||||||
|
|
||||||
ApplicationManager.getApplication().runReadAction(new Runnable() {
|
ApplicationManager.getApplication().runReadAction(new Runnable() {
|
||||||
public void run() {
|
public void run() {
|
||||||
try {
|
try {
|
||||||
PositionManager positionManager = getPositionManagerFactory().createPositionManager(debugProcess);
|
for (Breakpoint breakpoint : breakpoints) {
|
||||||
assertNotNull(positionManager);
|
SourcePosition position = SourcePosition.createFromLine(breakpoint.file, breakpoint.lineNumber);
|
||||||
for (Integer lineNumber : breakpoints.keySet()) {
|
assertPositionIsValid(position, breakpoint.className, positionManager);
|
||||||
String className = breakpoints.get(lineNumber);
|
|
||||||
SourcePosition position = SourcePosition.createFromLine(psiFile, lineNumber);
|
|
||||||
assertPositionIsValid(position, className, positionManager);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
catch (NoDataException e) {
|
catch (NoDataException e) {
|
||||||
@@ -126,24 +147,22 @@ public abstract class PositionManagerTestCase extends PlatformTestCase {
|
|||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
private static Map<Integer, String> extractBreakpointsInfo(String fileContent) {
|
private static Collection<Breakpoint> extractBreakpointsInfo(JetFile file, String fileContent) {
|
||||||
Map<Integer, String> breakpoints = Maps.newHashMap();
|
Collection<Breakpoint> breakpoints = Lists.newArrayList();
|
||||||
String[] lines = StringUtil.convertLineSeparators(fileContent).split("\n");
|
String[] lines = StringUtil.convertLineSeparators(fileContent).split("\n");
|
||||||
|
|
||||||
for (int i = 0; i < lines.length; i++) {
|
for (int i = 0; i < lines.length; i++) {
|
||||||
Matcher matcher = breakpointPattern.matcher(lines[i]);
|
Matcher matcher = breakpointPattern.matcher(lines[i]);
|
||||||
if (matcher.matches()) {
|
if (matcher.matches()) {
|
||||||
// Line breakpoint numbers are 1-based
|
// Line breakpoint numbers are 1-based
|
||||||
breakpoints.put(i + 1, matcher.group(1));
|
breakpoints.add(new Breakpoint(file, i + 1, matcher.group(1)));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return breakpoints;
|
return breakpoints;
|
||||||
}
|
}
|
||||||
|
|
||||||
private static Map<String, ReferenceType> compileFileGetReferenceMap(JetFile jetFile) {
|
private static Map<String, ReferenceType> getReferenceMap(ClassFileFactory classFileFactory) {
|
||||||
ClassFileFactory classFileFactory = GenerationUtils.compileFileGetClassFileFactoryForTest(jetFile);
|
|
||||||
|
|
||||||
Map<String, ReferenceType> referencesByName = Maps.newHashMap();
|
Map<String, ReferenceType> referencesByName = Maps.newHashMap();
|
||||||
for (String classFileName : classFileFactory.files()) {
|
for (String classFileName : classFileFactory.files()) {
|
||||||
String name = classFileName.substring(0, classFileName.lastIndexOf('.'));
|
String name = classFileName.substring(0, classFileName.lastIndexOf('.'));
|
||||||
@@ -176,6 +195,18 @@ public abstract class PositionManagerTestCase extends PlatformTestCase {
|
|||||||
assertEquals(className, type.name());
|
assertEquals(className, type.name());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private static class Breakpoint {
|
||||||
|
private final JetFile file;
|
||||||
|
private final int lineNumber;
|
||||||
|
private final String className;
|
||||||
|
|
||||||
|
private Breakpoint(JetFile file, int lineNumber, String className) {
|
||||||
|
this.file = file;
|
||||||
|
this.lineNumber = lineNumber;
|
||||||
|
this.className = className;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
private static class MockVirtualMachineProxy extends VirtualMachineProxyImpl {
|
private static class MockVirtualMachineProxy extends VirtualMachineProxyImpl {
|
||||||
private final Map<String, ReferenceType> referencesByName;
|
private final Map<String, ReferenceType> referencesByName;
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user