[java] navigation around decompiled code

Fixes IDEA-157772; reduces the number of cases where PsiCompiledFile check is necessary.
This commit is contained in:
Roman Shevchenko
2016-07-01 15:43:15 +03:00
parent 210243eadd
commit 7c2cb465cd
14 changed files with 51 additions and 111 deletions

View File

@@ -774,11 +774,7 @@ public abstract class DebuggerUtilsEx extends DebuggerUtils {
*/
@Nullable
public static PsiElement findElementAt(@Nullable PsiFile file, int offset) {
if (file instanceof PsiCompiledFile) {
file = ((PsiCompiledFile)file).getDecompiledPsiFile();
}
if (file == null) return null;
return file.findElementAt(offset);
return file != null ? file.findElementAt(offset) : null;
}
public static String getLocationMethodQName(@NotNull Location location) {

View File

@@ -215,14 +215,13 @@ public abstract class SourcePosition implements Navigatable{
@Nullable
protected PsiElement calcPsiElement() {
// currently PsiDocumentManager does not store documents for mirror file, so we store original file
PsiFile origPsiFile = getFile();
final PsiFile psiFile = origPsiFile instanceof PsiCompiledFile ? ((PsiCompiledFile)origPsiFile).getDecompiledPsiFile() : origPsiFile;
PsiFile psiFile = getFile();
int lineNumber = getLine();
if(lineNumber < 0) {
return psiFile;
}
final Document document = getDocument(origPsiFile);
final Document document = getDocument(getFile());
if (document == null) {
return null;
}

View File

@@ -1,5 +1,5 @@
/*
* Copyright 2000-2014 JetBrains s.r.o.
* Copyright 2000-2016 JetBrains s.r.o.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -49,9 +49,6 @@ public abstract class CopyPasteReferenceProcessor<TRef extends PsiElement> exten
return Collections.emptyList();
}
if (file instanceof PsiCompiledFile) {
file = ((PsiCompiledFile) file).getDecompiledPsiFile();
}
if (!(file instanceof PsiClassOwner)) {
return Collections.emptyList();
}
@@ -183,14 +180,7 @@ public abstract class CopyPasteReferenceProcessor<TRef extends PsiElement> exten
if (array.isEmpty()) return;
Object[] selectedObjects = ArrayUtil.toObjectArray(array);
Arrays.sort(
selectedObjects,
(o1, o2) -> {
String fqName1 = getFQName(o1);
String fqName2 = getFQName(o2);
return fqName1.compareToIgnoreCase(fqName2);
}
);
Arrays.sort(selectedObjects, (o1, o2) -> getFQName(o1).compareToIgnoreCase(getFQName(o2)));
RestoreReferencesDialog dialog = new RestoreReferencesDialog(project, selectedObjects);
dialog.show();
@@ -218,4 +208,4 @@ public abstract class CopyPasteReferenceProcessor<TRef extends PsiElement> exten
private static String getFQName(Object element) {
return element instanceof PsiClass ? ((PsiClass)element).getQualifiedName() : (String)element;
}
}
}

View File

@@ -16,6 +16,7 @@
package com.intellij.psi;
import com.intellij.ide.highlighter.JavaClassFileType;
import com.intellij.lang.Language;
import com.intellij.lang.java.JavaLanguage;
import com.intellij.openapi.components.ServiceManager;
import com.intellij.openapi.diagnostic.Logger;
@@ -124,4 +125,29 @@ public class ClassFileViewProvider extends SingleRootFileViewProvider {
public SingleRootFileViewProvider createCopy(@NotNull VirtualFile copy) {
return new ClassFileViewProvider(getManager(), copy, false);
}
@Override
public PsiElement findElementAt(int offset) {
return findElementAt(offset, getBaseLanguage());
}
@Override
public PsiElement findElementAt(int offset, @NotNull Language language) {
PsiFile file = getPsi(language);
if (file instanceof PsiCompiledFile) file = ((PsiCompiledFile)file).getDecompiledPsiFile();
return findElementAt(file, offset);
}
@Override
public PsiReference findReferenceAt(int offset) {
return findReferenceAt(offset, getBaseLanguage());
}
@Nullable
@Override
public PsiReference findReferenceAt(int offset, @NotNull Language language) {
PsiFile file = getPsi(language);
if (file instanceof PsiCompiledFile) file = ((PsiCompiledFile)file).getDecompiledPsiFile();
return findReferenceAt(file, offset);
}
}

View File

@@ -29,7 +29,6 @@ import com.intellij.psi.impl.PsiElementBase;
import com.intellij.psi.impl.source.SourceTreeToPsiMap;
import com.intellij.psi.impl.source.tree.TreeElement;
import com.intellij.psi.tree.IElementType;
import com.intellij.psi.util.PsiTreeUtil;
import com.intellij.psi.util.PsiUtilCore;
import com.intellij.util.ArrayUtil;
import com.intellij.util.IncorrectOperationException;
@@ -184,45 +183,13 @@ public abstract class ClsElementImpl extends PsiElementBase implements PsiCompil
@Override
public PsiElement findElementAt(int offset) {
PsiElement mirror = getMirror();
if (mirror == null) return null;
PsiElement mirrorAt = mirror.findElementAt(offset);
while (true) {
if (mirrorAt == null || mirrorAt instanceof PsiFile) return null;
PsiElement elementAt = mirrorToElement(mirrorAt);
if (elementAt != null) return elementAt;
mirrorAt = mirrorAt.getParent();
}
return mirror != null ? mirror.findElementAt(offset) : null;
}
@Override
public PsiReference findReferenceAt(int offset) {
PsiElement mirror = getMirror();
if (mirror == null) return null;
PsiReference mirrorRef = mirror.findReferenceAt(offset);
if (mirrorRef == null) return null;
PsiElement mirrorElement = mirrorRef.getElement();
PsiElement element = mirrorToElement(mirrorElement);
if (element == null) return null;
return element.getReference();
}
@Nullable
private PsiElement mirrorToElement(PsiElement mirror) {
final PsiElement m = getMirror();
if (m == mirror) return this;
PsiElement[] children = getChildren();
if (children.length == 0) return null;
for (PsiElement child : children) {
ClsElementImpl clsChild = (ClsElementImpl)child;
if (PsiTreeUtil.isAncestor(clsChild.getMirror(), mirror, false)) {
PsiElement element = clsChild.mirrorToElement(mirror);
if (element != null) return element;
}
}
return null;
return mirror != null ? mirror.findReferenceAt(offset) : null;
}
@Override

View File

@@ -1,5 +1,5 @@
/*
* Copyright 2000-2015 JetBrains s.r.o.
* Copyright 2000-2016 JetBrains s.r.o.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -480,7 +480,7 @@ public class SingleRootFileViewProvider extends UserDataHolderBase implements Fi
}
@Nullable
private static PsiReference findReferenceAt(@Nullable final PsiFile psiFile, final int offset) {
protected static PsiReference findReferenceAt(@Nullable final PsiFile psiFile, final int offset) {
if (psiFile == null) return null;
int offsetInElement = offset;
PsiElement child = psiFile.getFirstChild();

View File

@@ -130,7 +130,7 @@ public class TargetElementUtil extends TargetElementUtilBase {
if (project == null) return null;
Document document = editor.getDocument();
PsiFile file = getFile(project, document);
PsiFile file = PsiDocumentManager.getInstance(project).getPsiFile(document);
if (file == null) return null;
offset = adjustOffset(file, document, offset);
@@ -138,11 +138,6 @@ public class TargetElementUtil extends TargetElementUtilBase {
return file.findReferenceAt(offset);
}
private static PsiFile getFile(Project project, Document document) {
PsiFile file = PsiDocumentManager.getInstance(project).getPsiFile(document);
return file instanceof PsiCompiledFile ? ((PsiCompiledFile)file).getDecompiledPsiFile() : file;
}
/**
* @deprecated adjust offset with PsiElement should be used instead to provide correct checking for identifier part
*/
@@ -233,7 +228,7 @@ public class TargetElementUtil extends TargetElementUtilBase {
}
Document document = editor.getDocument();
PsiFile file = getFile(project, document);
PsiFile file = PsiDocumentManager.getInstance(project).getPsiFile(document);
if (file == null) return null;
offset = adjustOffset(file, document, offset);

View File

@@ -205,7 +205,6 @@ public class QuickDocOnMouseOverManager {
}
PsiFile psiFile = PsiDocumentManager.getInstance(project).getPsiFile(editor.getDocument());
if (psiFile instanceof PsiCompiledFile) psiFile = ((PsiCompiledFile)psiFile).getDecompiledPsiFile();
if (psiFile == null) {
closeQuickDocIfPossible();
return;

View File

@@ -1,5 +1,5 @@
/*
* Copyright 2000-2015 JetBrains s.r.o.
* Copyright 2000-2016 JetBrains s.r.o.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -33,10 +33,12 @@ import com.intellij.openapi.project.Project;
import com.intellij.openapi.util.Ref;
import com.intellij.openapi.util.TextRange;
import com.intellij.openapi.util.text.StringUtil;
import com.intellij.psi.*;
import com.intellij.psi.PsiDocumentManager;
import com.intellij.psi.PsiElement;
import com.intellij.psi.PsiFile;
import com.intellij.psi.PsiWhiteSpace;
import com.intellij.psi.impl.DebugUtil;
import com.intellij.psi.templateLanguages.OuterLanguageElement;
import com.intellij.util.Processor;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
@@ -96,9 +98,6 @@ public class SelectWordHandler extends EditorActionHandler {
private static TextRange selectWord(@NotNull Editor editor, @NotNull Project project) {
Document document = editor.getDocument();
PsiFile file = PsiDocumentManager.getInstance(project).getPsiFile(document);
if (file instanceof PsiCompiledFile) {
file = ((PsiCompiledFile)file).getDecompiledPsiFile();
}
if (file == null) return null;
FeatureUsageTracker.getInstance().triggerFeatureUsed("editing.select.word");

View File

@@ -1,5 +1,5 @@
/*
* Copyright 2000-2014 JetBrains s.r.o.
* Copyright 2000-2016 JetBrains s.r.o.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -59,13 +59,7 @@ public class UnSelectWordHandler extends EditorActionHandler {
doAction(editor, file);
}
private static void doAction(final Editor editor, PsiFile file) {
if (file instanceof PsiCompiledFile) {
file = ((PsiCompiledFile)file).getDecompiledPsiFile();
if (file == null) return;
}
if (!editor.getSelectionModel().hasSelection()) {
return;
}

View File

@@ -1,5 +1,5 @@
/*
* Copyright 2000-2015 JetBrains s.r.o.
* Copyright 2000-2016 JetBrains s.r.o.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -126,13 +126,7 @@ public class BraceHighlightingHandler {
if (!ApplicationManagerEx.getApplicationEx().tryRunReadAction(() -> {
final PsiFile injected;
try {
if (psiFile instanceof PsiCompiledFile) {
injected = ((PsiCompiledFile)psiFile).getDecompiledPsiFile();
}
else if (psiFile instanceof PsiCompiledElement ||
psiFile instanceof PsiBinaryFile ||
!isValidEditor(editor) ||
!isValidFile(psiFile)) {
if (psiFile instanceof PsiBinaryFile || !isValidEditor(editor) || !isValidFile(psiFile)) {
injected = null;
}
else {

View File

@@ -1,5 +1,5 @@
/*
* Copyright 2000-2015 JetBrains s.r.o.
* Copyright 2000-2016 JetBrains s.r.o.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -263,15 +263,10 @@ public class GotoDeclarationAction extends BaseCodeInsightAction implements Code
@Nullable
public static PsiElement[] findTargetElementsNoVS(Project project, Editor editor, int offset, boolean lookupAccepted) {
final Document document = editor.getDocument();
Document document = editor.getDocument();
PsiFile file = PsiDocumentManager.getInstance(project).getPsiFile(document);
if (file == null) return null;
if (file instanceof PsiCompiledFile) {
PsiFile decompiled = ((PsiCompiledFile)file).getDecompiledPsiFile();
if (decompiled != null) file = decompiled;
}
PsiElement elementAt = file.findElementAt(TargetElementUtil.adjustOffset(file, document, offset));
for (GotoDeclarationHandler handler : Extensions.getExtensions(GotoDeclarationHandler.EP_NAME)) {
try {

View File

@@ -473,10 +473,6 @@ public class XDebuggerUtilImpl extends XDebuggerUtil {
PsiElement element;
int offset = lineStart;
if (file instanceof PsiCompiledFile) {
file = ((PsiCompiledFile)file).getDecompiledPsiFile();
}
while (offset < lineEnd) {
element = file.findElementAt(offset);
if (element != null) {
@@ -511,10 +507,6 @@ public class XDebuggerUtilImpl extends XDebuggerUtil {
return null;
}
if (file instanceof PsiCompiledFile) {
file = ((PsiCompiledFile)file).getDecompiledPsiFile();
}
if (offset < 0) {
offset = 0;
}

View File

@@ -83,7 +83,7 @@ public class ShowByteCodeAction extends AnAction {
final RelativePoint bestPopupLocation = JBPopupFactory.getInstance().guessBestPopupLocation(dataContext);
final SmartPsiElementPointer element = SmartPointerManager.getInstance(project).createSmartPsiElementPointer(psiElement);
ProgressManager.getInstance().run(new Task.Backgroundable(project, "Looking for bytecode...") {
ProgressManager.getInstance().run(new Task.Backgroundable(project, "Looking for Bytecode...") {
private String myByteCode;
private String myErrorMessage;
private String myErrorTitle;
@@ -179,12 +179,6 @@ public class ShowByteCodeAction extends AnAction {
}
private static PsiElement findElementInFile(@Nullable PsiFile psiFile, Editor editor) {
if (psiFile == null) {
return null;
}
if (psiFile instanceof PsiCompiledFile) {
psiFile = ((PsiCompiledFile)psiFile).getDecompiledPsiFile();
}
return psiFile.findElementAt(editor.getCaretModel().getOffset());
return psiFile != null ? psiFile.findElementAt(editor.getCaretModel().getOffset()) : null;
}
}
}