use of com.intellij.openapi.util.Ref in project kotlin by JetBrains.
the class CompileKotlinAgainstCustomBinariesTest method testInlineFunWithoutDebugInfo.
/*test source mapping generation when source info is absent*/
public void testInlineFunWithoutDebugInfo() throws Exception {
compileKotlin("sourceInline.kt", tmpdir);
File inlineFunClass = new File(tmpdir.getAbsolutePath(), "test/A.class");
ClassWriter cw = new ClassWriter(Opcodes.ASM5);
new ClassReader(FilesKt.readBytes(inlineFunClass)).accept(new ClassVisitor(Opcodes.ASM5, cw) {
@Override
public void visitSource(String source, String debug) {
//skip debug info
}
}, 0);
assert inlineFunClass.delete();
assert !inlineFunClass.exists();
FilesKt.writeBytes(inlineFunClass, cw.toByteArray());
compileKotlin("source.kt", tmpdir, tmpdir);
final Ref<String> debugInfo = new Ref<String>();
File resultFile = new File(tmpdir.getAbsolutePath(), "test/B.class");
new ClassReader(FilesKt.readBytes(resultFile)).accept(new ClassVisitor(Opcodes.ASM5) {
@Override
public void visitSource(String source, String debug) {
//skip debug info
debugInfo.set(debug);
}
}, 0);
String expected = "SMAP\n" + "source.kt\n" + "Kotlin\n" + "*S Kotlin\n" + "*F\n" + "+ 1 source.kt\n" + "test/B\n" + "*L\n" + "1#1,13:1\n" + "*E\n";
if (InlineCodegenUtil.GENERATE_SMAP) {
assertEquals(expected, debugInfo.get());
} else {
assertEquals(null, debugInfo.get());
}
}
use of com.intellij.openapi.util.Ref in project intellij-community by JetBrains.
the class CucumberMain method run.
public static int run(final String[] argv, final ClassLoader classLoader) throws IOException {
final Ref<Throwable> errorRef = new Ref<>();
final Ref<Runtime> runtimeRef = new Ref<>();
try {
TestRunnerUtil.replaceIdeEventQueueSafely();
UIUtil.invokeAndWaitIfNeeded(new Runnable() {
@Override
public void run() {
try {
RuntimeOptions runtimeOptions = new RuntimeOptions(new ArrayList(Arrays.asList(argv)));
MultiLoader resourceLoader = new MultiLoader(classLoader);
ResourceLoaderClassFinder classFinder = new ResourceLoaderClassFinder(resourceLoader, classLoader);
Runtime runtime = new Runtime(resourceLoader, classFinder, classLoader, runtimeOptions);
runtimeRef.set(runtime);
runtime.run();
} catch (Throwable throwable) {
errorRef.set(throwable);
Logger.getInstance(CucumberMain.class).error(throwable);
}
}
});
} catch (Throwable t) {
errorRef.set(t);
Logger.getInstance(CucumberMain.class).error(t);
}
final Throwable throwable = errorRef.get();
if (throwable != null) {
throwable.printStackTrace();
}
System.err.println("Failed tests :");
for (Throwable error : runtimeRef.get().getErrors()) {
error.printStackTrace();
System.err.println("=============================");
}
return throwable != null ? 1 : 0;
}
use of com.intellij.openapi.util.Ref in project intellij-community by JetBrains.
the class JavaValue method computeChildren.
@Override
public void computeChildren(@NotNull final XCompositeNode node) {
scheduleCommand(myEvaluationContext, node, new SuspendContextCommandImpl(myEvaluationContext.getSuspendContext()) {
@Override
public Priority getPriority() {
return Priority.NORMAL;
}
@Override
public void contextAction() throws Exception {
final XValueChildrenList children = new XValueChildrenList();
final NodeRenderer renderer = myValueDescriptor.getRenderer(myEvaluationContext.getDebugProcess());
final Ref<Integer> remainingNum = new Ref<>(0);
renderer.buildChildren(myValueDescriptor.getValue(), new ChildrenBuilder() {
@Override
public NodeDescriptorFactory getDescriptorManager() {
return myNodeManager;
}
@Override
public NodeManager getNodeManager() {
return myNodeManager;
}
@Override
public ValueDescriptor getParentDescriptor() {
return myValueDescriptor;
}
@Override
public void setRemaining(int remaining) {
remainingNum.set(remaining);
}
@Override
public void initChildrenArrayRenderer(ArrayRenderer renderer) {
renderer.START_INDEX = myCurrentChildrenStart;
renderer.END_INDEX = myCurrentChildrenStart + XCompositeNode.MAX_CHILDREN_TO_SHOW - 1;
myCurrentChildrenStart += XCompositeNode.MAX_CHILDREN_TO_SHOW;
}
@Override
public void setChildren(List<DebuggerTreeNode> nodes) {
for (DebuggerTreeNode node : nodes) {
final NodeDescriptor descriptor = node.getDescriptor();
if (descriptor instanceof ValueDescriptorImpl) {
// Value is calculated already in NodeManagerImpl
children.add(create(JavaValue.this, (ValueDescriptorImpl) descriptor, myEvaluationContext, myNodeManager, false));
} else if (descriptor instanceof MessageDescriptor) {
children.add(new JavaStackFrame.DummyMessageValueNode(descriptor.getLabel(), null));
}
}
}
}, myEvaluationContext);
node.addChildren(children, true);
if (remainingNum.get() > 0) {
node.tooManyChildren(remainingNum.get());
}
}
});
}
use of com.intellij.openapi.util.Ref in project intellij-community by JetBrains.
the class JavaMarkObjectActionHandler method perform.
@Override
public void perform(@NotNull Project project, AnActionEvent event) {
final DebuggerTreeNodeImpl node = DebuggerAction.getSelectedNode(event.getDataContext());
if (node == null) {
return;
}
final NodeDescriptorImpl descriptor = node.getDescriptor();
if (!(descriptor instanceof ValueDescriptorImpl)) {
return;
}
final DebuggerTree tree = node.getTree();
tree.saveState(node);
final Component parent = event.getData(CONTEXT_COMPONENT);
final ValueDescriptorImpl valueDescriptor = ((ValueDescriptorImpl) descriptor);
final DebuggerContextImpl debuggerContext = tree.getDebuggerContext();
final DebugProcessImpl debugProcess = debuggerContext.getDebugProcess();
final ValueMarkup markup = valueDescriptor.getMarkup(debugProcess);
debugProcess.getManagerThread().invoke(new DebuggerContextCommandImpl(debuggerContext) {
public Priority getPriority() {
return Priority.HIGH;
}
public void threadAction() {
boolean sessionRefreshNeeded = true;
try {
if (markup != null) {
valueDescriptor.setMarkup(debugProcess, null);
} else {
final String defaultText = valueDescriptor.getName();
final Ref<Pair<ValueMarkup, Boolean>> result = new Ref<>(null);
try {
final boolean suggestAdditionalMarkup = canSuggestAdditionalMarkup(debugProcess, valueDescriptor.getValue());
SwingUtilities.invokeAndWait(() -> {
ObjectMarkupPropertiesDialog dialog = new ObjectMarkupPropertiesDialog(parent, defaultText, suggestAdditionalMarkup);
if (dialog.showAndGet()) {
result.set(Pair.create(dialog.getConfiguredMarkup(), dialog.isMarkAdditionalFields()));
}
});
} catch (InterruptedException ignored) {
} catch (InvocationTargetException e) {
LOG.error(e);
}
final Pair<ValueMarkup, Boolean> pair = result.get();
if (pair != null) {
valueDescriptor.setMarkup(debugProcess, pair.first);
if (pair.second) {
final Value value = valueDescriptor.getValue();
final Map<ObjectReference, ValueMarkup> additionalMarkup = suggestMarkup((ObjectReference) value);
if (!additionalMarkup.isEmpty()) {
final Map<ObjectReference, ValueMarkup> map = NodeDescriptorImpl.getMarkupMap(debugProcess);
if (map != null) {
for (Map.Entry<ObjectReference, ValueMarkup> entry : additionalMarkup.entrySet()) {
final ObjectReference key = entry.getKey();
if (!map.containsKey(key)) {
map.put(key, entry.getValue());
}
}
}
}
}
} else {
sessionRefreshNeeded = false;
}
}
} finally {
final boolean _sessionRefreshNeeded = sessionRefreshNeeded;
SwingUtilities.invokeLater(new Runnable() {
public void run() {
tree.restoreState(node);
final TreeBuilder model = tree.getMutableModel();
refreshLabelsRecursively(model.getRoot(), model, valueDescriptor.getValue());
if (_sessionRefreshNeeded) {
final DebuggerSession session = debuggerContext.getDebuggerSession();
if (session != null) {
session.refresh(true);
}
}
}
private void refreshLabelsRecursively(Object node, TreeBuilder model, Value value) {
if (node instanceof DebuggerTreeNodeImpl) {
final DebuggerTreeNodeImpl _node = (DebuggerTreeNodeImpl) node;
final NodeDescriptorImpl descriptor = _node.getDescriptor();
if (descriptor instanceof ValueDescriptor && Comparing.equal(value, ((ValueDescriptor) descriptor).getValue())) {
_node.labelChanged();
}
}
final int childCount = model.getChildCount(node);
for (int idx = 0; idx < childCount; idx++) {
refreshLabelsRecursively(model.getChild(node, idx), model, value);
}
}
});
}
}
});
}
use of com.intellij.openapi.util.Ref in project intellij-community by JetBrains.
the class JavaSmartStepIntoHandler method findSmartStepTargets.
protected List<SmartStepTarget> findSmartStepTargets(final SourcePosition position, @Nullable SuspendContextImpl suspendContext, @NotNull DebuggerContextImpl debuggerContext) {
final int line = position.getLine();
if (line < 0) {
// the document has been changed
return Collections.emptyList();
}
final PsiFile file = position.getFile();
final VirtualFile vFile = file.getVirtualFile();
if (vFile == null) {
// the file is not physical
return Collections.emptyList();
}
final Document doc = FileDocumentManager.getInstance().getDocument(vFile);
if (doc == null)
return Collections.emptyList();
if (line >= doc.getLineCount()) {
// the document has been changed
return Collections.emptyList();
}
TextRange curLineRange = DocumentUtil.getLineTextRange(doc, line);
PsiElement element = position.getElementAt();
PsiElement body = DebuggerUtilsEx.getBody(DebuggerUtilsEx.getContainingMethod(element));
final TextRange lineRange = (body != null) ? curLineRange.intersection(body.getTextRange()) : curLineRange;
if (lineRange == null || lineRange.isEmpty()) {
return Collections.emptyList();
}
if (element != null && !(element instanceof PsiCompiledElement)) {
do {
final PsiElement parent = element.getParent();
if (parent == null || (parent.getTextOffset() < lineRange.getStartOffset())) {
break;
}
element = parent;
} while (true);
//noinspection unchecked
final List<SmartStepTarget> targets = new OrderedSet<>();
final Ref<TextRange> textRange = new Ref<>(lineRange);
final PsiElementVisitor methodCollector = new JavaRecursiveElementVisitor() {
final Deque<PsiMethod> myContextStack = new LinkedList<>();
final Deque<String> myParamNameStack = new LinkedList<>();
private int myNextLambdaExpressionOrdinal = 0;
private boolean myInsideLambda = false;
@Nullable
private String getCurrentParamName() {
return myParamNameStack.peekFirst();
}
@Override
public void visitAnonymousClass(PsiAnonymousClass aClass) {
for (PsiMethod psiMethod : aClass.getMethods()) {
targets.add(0, new MethodSmartStepTarget(psiMethod, getCurrentParamName(), psiMethod.getBody(), true, null));
}
}
public void visitLambdaExpression(PsiLambdaExpression expression) {
boolean inLambda = myInsideLambda;
myInsideLambda = true;
super.visitLambdaExpression(expression);
myInsideLambda = inLambda;
targets.add(0, new LambdaSmartStepTarget(expression, getCurrentParamName(), expression.getBody(), myNextLambdaExpressionOrdinal++, null, !myInsideLambda));
}
@Override
public void visitMethodReferenceExpression(PsiMethodReferenceExpression expression) {
PsiElement element = expression.resolve();
if (element instanceof PsiMethod) {
PsiElement navMethod = element.getNavigationElement();
if (navMethod instanceof PsiMethod) {
targets.add(0, new MethodSmartStepTarget(((PsiMethod) navMethod), null, expression, true, null));
}
}
}
@Override
public void visitField(PsiField field) {
if (checkTextRange(field, false)) {
super.visitField(field);
}
}
@Override
public void visitMethod(PsiMethod method) {
if (checkTextRange(method, false)) {
super.visitMethod(method);
}
}
@Override
public void visitStatement(PsiStatement statement) {
if (checkTextRange(statement, true)) {
super.visitStatement(statement);
}
}
@Override
public void visitIfStatement(PsiIfStatement statement) {
visitConditional(statement.getCondition(), statement.getThenBranch(), statement.getElseBranch());
}
@Override
public void visitConditionalExpression(PsiConditionalExpression expression) {
visitConditional(expression.getCondition(), expression.getThenExpression(), expression.getElseExpression());
}
private void visitConditional(@Nullable PsiElement condition, @Nullable PsiElement thenBranch, @Nullable PsiElement elseBranch) {
if (condition != null && checkTextRange(condition, true)) {
condition.accept(this);
}
ThreeState conditionRes = evaluateCondition(condition);
if (conditionRes != ThreeState.NO && thenBranch != null && checkTextRange(thenBranch, true)) {
thenBranch.accept(this);
}
if (conditionRes != ThreeState.YES && elseBranch != null && checkTextRange(elseBranch, true)) {
elseBranch.accept(this);
}
}
private ThreeState evaluateCondition(@Nullable PsiElement condition) {
if (condition != null && !DebuggerUtils.hasSideEffects(condition)) {
try {
ExpressionEvaluator evaluator = EvaluatorBuilderImpl.getInstance().build(condition, position);
return ThreeState.fromBoolean(DebuggerUtilsEx.evaluateBoolean(evaluator, debuggerContext.createEvaluationContext()));
} catch (EvaluateException e) {
LOG.info(e);
}
}
return ThreeState.UNSURE;
}
@Override
public void visitExpression(PsiExpression expression) {
checkTextRange(expression, true);
super.visitExpression(expression);
}
boolean checkTextRange(@NotNull PsiElement expression, boolean expand) {
TextRange range = expression.getTextRange();
if (lineRange.intersects(range)) {
if (expand) {
textRange.set(textRange.get().union(range));
}
return true;
}
return false;
}
public void visitExpressionList(PsiExpressionList expressionList) {
PsiMethod psiMethod = myContextStack.peekFirst();
if (psiMethod != null) {
final String methodName = psiMethod.getName();
final PsiExpression[] expressions = expressionList.getExpressions();
final PsiParameter[] parameters = psiMethod.getParameterList().getParameters();
for (int idx = 0; idx < expressions.length; idx++) {
final String paramName = (idx < parameters.length && !parameters[idx].isVarArgs()) ? parameters[idx].getName() : "arg" + (idx + 1);
myParamNameStack.push(methodName + ": " + paramName + ".");
final PsiExpression argExpression = expressions[idx];
try {
argExpression.accept(this);
} finally {
myParamNameStack.pop();
}
}
} else {
super.visitExpressionList(expressionList);
}
}
@Override
public void visitCallExpression(final PsiCallExpression expression) {
final PsiMethod psiMethod = expression.resolveMethod();
if (psiMethod != null) {
myContextStack.push(psiMethod);
targets.add(new MethodSmartStepTarget(psiMethod, null, expression instanceof PsiMethodCallExpression ? ((PsiMethodCallExpression) expression).getMethodExpression().getReferenceNameElement() : expression instanceof PsiNewExpression ? ((PsiNewExpression) expression).getClassOrAnonymousClassReference() : expression, myInsideLambda, null));
}
try {
super.visitCallExpression(expression);
} finally {
if (psiMethod != null) {
myContextStack.pop();
}
}
}
};
element.accept(methodCollector);
for (PsiElement sibling = element.getNextSibling(); sibling != null; sibling = sibling.getNextSibling()) {
if (!lineRange.intersects(sibling.getTextRange())) {
break;
}
sibling.accept(methodCollector);
}
Range<Integer> lines = new Range<>(doc.getLineNumber(textRange.get().getStartOffset()), doc.getLineNumber(textRange.get().getEndOffset()));
targets.forEach(t -> t.setCallingExpressionLines(lines));
if (!targets.isEmpty()) {
StackFrameProxyImpl frameProxy = suspendContext != null ? suspendContext.getFrameProxy() : null;
if (frameProxy != null) {
try {
Location location = frameProxy.location();
MethodBytecodeUtil.visit(location.method(), location.codeIndex(), new MethodVisitor(Opcodes.API_VERSION) {
boolean myLineMatch = false;
@Override
public void visitLineNumber(int line, Label start) {
myLineMatch = lines.isWithin(line - 1);
}
@Override
public void visitMethodInsn(int opcode, String owner, String name, String desc, boolean itf) {
if (myLineMatch) {
targets.removeIf(t -> {
if (t instanceof MethodSmartStepTarget) {
return DebuggerUtilsEx.methodMatches(((MethodSmartStepTarget) t).getMethod(), owner.replace("/", "."), name, desc, suspendContext.getDebugProcess());
}
return false;
});
}
}
}, true);
} catch (Exception e) {
LOG.info(e);
}
}
return targets;
}
}
return Collections.emptyList();
}
Aggregations