mirror of
https://gitflic.ru/project/openide/openide.git
synced 2026-09-27 10:03:11 +07:00
IDEA-87003
This commit is contained in:
@@ -23,6 +23,7 @@ import com.intellij.openapi.editor.Editor;
|
||||
import com.intellij.psi.PsiElement;
|
||||
import com.intellij.psi.PsiFile;
|
||||
import com.intellij.psi.PsiJavaCodeReferenceElement;
|
||||
import com.intellij.psi.PsiReference;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
|
||||
import java.util.List;
|
||||
@@ -56,4 +57,19 @@ public class JavaReferenceImporter implements ReferenceImporter {
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean autoImportReferenceAt(@NotNull Editor editor, @NotNull PsiFile file, int offset) {
|
||||
if (!file.getViewProvider().getLanguages().contains(StdLanguages.JAVA)) return false;
|
||||
PsiReference element = file.findReferenceAt(offset);
|
||||
|
||||
if (element instanceof PsiJavaCodeReferenceElement) {
|
||||
PsiJavaCodeReferenceElement ref = (PsiJavaCodeReferenceElement)element;
|
||||
if (ref.multiResolve(true).length == 0) {
|
||||
new ImportClassFix(ref).doFix(editor, false, true);
|
||||
return true;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
+6
-5
@@ -36,12 +36,12 @@ public class ImportClassFix extends ImportClassFixBase<PsiJavaCodeReferenceEleme
|
||||
}
|
||||
|
||||
@Override
|
||||
protected String getReferenceName(PsiJavaCodeReferenceElement reference) {
|
||||
protected String getReferenceName(@NotNull PsiJavaCodeReferenceElement reference) {
|
||||
return reference.getReferenceName();
|
||||
}
|
||||
|
||||
@Override
|
||||
protected PsiElement getReferenceNameElement(PsiJavaCodeReferenceElement reference) {
|
||||
protected PsiElement getReferenceNameElement(@NotNull PsiJavaCodeReferenceElement reference) {
|
||||
return reference.getReferenceNameElement();
|
||||
}
|
||||
|
||||
@@ -56,7 +56,7 @@ public class ImportClassFix extends ImportClassFixBase<PsiJavaCodeReferenceEleme
|
||||
}
|
||||
|
||||
@Override
|
||||
protected boolean hasTypeParameters(PsiJavaCodeReferenceElement reference) {
|
||||
protected boolean hasTypeParameters(@NotNull PsiJavaCodeReferenceElement reference) {
|
||||
final PsiReferenceParameterList refParameters = reference.getParameterList();
|
||||
return refParameters != null && refParameters.getTypeParameterElements().length > 0;
|
||||
}
|
||||
@@ -97,8 +97,9 @@ public class ImportClassFix extends ImportClassFixBase<PsiJavaCodeReferenceEleme
|
||||
|
||||
@Override
|
||||
protected String getRequiredMemberName(PsiJavaCodeReferenceElement reference) {
|
||||
if (reference.getParent() instanceof PsiJavaCodeReferenceElement) {
|
||||
return ((PsiJavaCodeReferenceElement)reference.getParent()).getReferenceName();
|
||||
PsiElement parent = reference.getParent();
|
||||
if (parent instanceof PsiJavaCodeReferenceElement) {
|
||||
return ((PsiJavaCodeReferenceElement)parent).getReferenceName();
|
||||
}
|
||||
|
||||
return super.getRequiredMemberName(reference);
|
||||
|
||||
+6
-7
@@ -72,10 +72,9 @@ public abstract class ImportClassFixBase<T extends PsiElement & PsiReference> im
|
||||
}
|
||||
|
||||
@Nullable
|
||||
protected abstract String getReferenceName(T reference);
|
||||
protected abstract PsiElement getReferenceNameElement(T reference);
|
||||
|
||||
protected abstract boolean hasTypeParameters(T reference);
|
||||
protected abstract String getReferenceName(@NotNull T reference);
|
||||
protected abstract PsiElement getReferenceNameElement(@NotNull T reference);
|
||||
protected abstract boolean hasTypeParameters(@NotNull T reference);
|
||||
|
||||
@NotNull
|
||||
public List<PsiClass> getClassesToImport() {
|
||||
@@ -145,7 +144,7 @@ public abstract class ImportClassFixBase<T extends PsiElement & PsiReference> im
|
||||
POPUP_NOT_SHOWN
|
||||
}
|
||||
|
||||
public Result doFix(@NotNull final Editor editor, boolean doShow, final boolean allowCaretNearRef) {
|
||||
public Result doFix(@NotNull final Editor editor, boolean allowPopup, final boolean allowCaretNearRef) {
|
||||
List<PsiClass> classesToImport = getClassesToImport();
|
||||
if (classesToImport.isEmpty()) return Result.POPUP_NOT_SHOWN;
|
||||
|
||||
@@ -194,7 +193,7 @@ public abstract class ImportClassFixBase<T extends PsiElement & PsiReference> im
|
||||
return Result.CLASS_AUTO_IMPORTED;
|
||||
}
|
||||
|
||||
if (doShow && canImportHere) {
|
||||
if (allowPopup && canImportHere) {
|
||||
String hintText = ShowAutoImportPass.getMessage(classes.length > 1, classes[0].getQualifiedName());
|
||||
if (!ApplicationManager.getApplication().isUnitTestMode() && !HintManager.getInstance().hasShownHintsThatWillHideByOtherHint(true)) {
|
||||
HintManager.getInstance().showQuestionHint(editor, hintText, myRef.getTextOffset(),
|
||||
@@ -261,7 +260,7 @@ public abstract class ImportClassFixBase<T extends PsiElement & PsiReference> im
|
||||
}
|
||||
}
|
||||
|
||||
private boolean isCaretNearRef(Editor editor, T ref) {
|
||||
private boolean isCaretNearRef(@NotNull Editor editor, @NotNull T ref) {
|
||||
PsiElement nameElement = getReferenceNameElement(ref);
|
||||
if (nameElement == null) return false;
|
||||
TextRange range = nameElement.getTextRange();
|
||||
|
||||
@@ -5,6 +5,7 @@ import com.intellij.codeInsight.daemon.impl.DaemonCodeAnalyzerImpl;
|
||||
import com.intellij.codeInsight.daemon.impl.HighlightInfo;
|
||||
import com.intellij.codeInsight.daemon.impl.quickfix.ImportClassFix;
|
||||
import com.intellij.codeInsight.daemon.impl.quickfix.ImportClassFixBase;
|
||||
import com.intellij.codeInsight.generation.actions.CommentByBlockCommentAction;
|
||||
import com.intellij.codeInspection.LocalInspectionTool;
|
||||
import com.intellij.codeInspection.unusedImport.UnusedImportLocalInspection;
|
||||
import com.intellij.openapi.application.ApplicationManager;
|
||||
@@ -306,6 +307,31 @@ public class ImportHelperTest extends DaemonAnalyzerTestCase {
|
||||
}
|
||||
}
|
||||
|
||||
public void testAutoImportAfterUncomment() throws Throwable {
|
||||
@NonNls String text = "class S { /*ArrayList l; HashMap h; <caret>*/ }";
|
||||
configureByText(StdFileTypes.JAVA, text);
|
||||
|
||||
boolean old = CodeInsightSettings.getInstance().ADD_UNAMBIGIOUS_IMPORTS_ON_THE_FLY;
|
||||
CodeInsightSettings.getInstance().ADD_UNAMBIGIOUS_IMPORTS_ON_THE_FLY = true;
|
||||
DaemonCodeAnalyzerSettings.getInstance().setImportHintEnabled(true);
|
||||
|
||||
try {
|
||||
doHighlighting();
|
||||
|
||||
assertEmpty(((PsiJavaFile)getFile()).getImportList().getAllImportStatements());
|
||||
|
||||
CommentByBlockCommentAction action = new CommentByBlockCommentAction();
|
||||
action.actionPerformedImpl(getProject(), getEditor());
|
||||
|
||||
assertEmpty(highlightErrors());
|
||||
|
||||
assertNotSame(0, ((PsiJavaFile)getFile()).getImportList().getAllImportStatements().length);
|
||||
}
|
||||
finally {
|
||||
CodeInsightSettings.getInstance().ADD_UNAMBIGIOUS_IMPORTS_ON_THE_FLY = old;
|
||||
}
|
||||
}
|
||||
|
||||
public void testAutoImportWorks() throws Throwable {
|
||||
@NonNls final String text = "class S { JFrame x; <caret> }";
|
||||
configureByText(StdFileTypes.JAVA, text);
|
||||
@@ -325,6 +351,7 @@ public class ImportHelperTest extends DaemonAnalyzerTestCase {
|
||||
assertFalse(((DaemonCodeAnalyzerImpl)DaemonCodeAnalyzer.getInstance(getProject())).canChangeFileSilently(getFile()));//CodeInsightSettings.getInstance().ADD_UNAMBIGIOUS_IMPORTS_ON_THE_FLY = old;
|
||||
}
|
||||
|
||||
|
||||
public void testAutoImportOfGenericReference() throws Throwable {
|
||||
@NonNls final String text = "class S {{ new ArrayList<caret><> }}";
|
||||
configureByText(StdFileTypes.JAVA, text);
|
||||
|
||||
@@ -28,4 +28,5 @@ public interface ReferenceImporter {
|
||||
ExtensionPointName<ReferenceImporter> EP_NAME = ExtensionPointName.create("com.intellij.referenceImporter");
|
||||
|
||||
boolean autoImportReferenceAtCursor(@NotNull Editor editor, @NotNull PsiFile file);
|
||||
boolean autoImportReferenceAt(@NotNull Editor editor, @NotNull PsiFile file, int offset);
|
||||
}
|
||||
|
||||
+34
-1
@@ -17,16 +17,21 @@
|
||||
package com.intellij.codeInsight.daemon.impl;
|
||||
|
||||
import com.intellij.codeHighlighting.TextEditorHighlightingPass;
|
||||
import com.intellij.codeInsight.CodeInsightSettings;
|
||||
import com.intellij.codeInsight.daemon.DaemonBundle;
|
||||
import com.intellij.codeInsight.daemon.DaemonCodeAnalyzer;
|
||||
import com.intellij.codeInsight.daemon.DaemonCodeAnalyzerSettings;
|
||||
import com.intellij.codeInsight.daemon.ReferenceImporter;
|
||||
import com.intellij.codeInsight.intention.IntentionAction;
|
||||
import com.intellij.codeInspection.HintAction;
|
||||
import com.intellij.lang.annotation.HighlightSeverity;
|
||||
import com.intellij.openapi.actionSystem.ActionManager;
|
||||
import com.intellij.openapi.actionSystem.IdeActions;
|
||||
import com.intellij.openapi.application.Application;
|
||||
import com.intellij.openapi.application.ApplicationManager;
|
||||
import com.intellij.openapi.editor.Document;
|
||||
import com.intellij.openapi.editor.Editor;
|
||||
import com.intellij.openapi.extensions.Extensions;
|
||||
import com.intellij.openapi.keymap.KeymapUtil;
|
||||
import com.intellij.openapi.progress.ProgressIndicator;
|
||||
import com.intellij.openapi.project.Project;
|
||||
@@ -70,9 +75,10 @@ public class ShowAutoImportPass extends TextEditorHighlightingPass {
|
||||
Application application = ApplicationManager.getApplication();
|
||||
application.assertIsDispatchThread();
|
||||
if (!application.isUnitTestMode() && !myEditor.getContentComponent().hasFocus()) return;
|
||||
int caretOffset = myEditor.getCaretModel().getOffset();
|
||||
importUnambiguousImports(caretOffset);
|
||||
List<HighlightInfo> visibleHighlights = getVisibleHighlights(myStartOffset, myEndOffset, myProject, myEditor);
|
||||
|
||||
int caretOffset = myEditor.getCaretModel().getOffset();
|
||||
for (int i = visibleHighlights.size() - 1; i >= 0; i--) {
|
||||
HighlightInfo info = visibleHighlights.get(i);
|
||||
if (info.startOffset <= caretOffset && showAddImportHint(info)) return;
|
||||
@@ -83,6 +89,33 @@ public class ShowAutoImportPass extends TextEditorHighlightingPass {
|
||||
}
|
||||
}
|
||||
|
||||
private void importUnambiguousImports(final int caretOffset) {
|
||||
if (!DaemonCodeAnalyzerSettings.getInstance().isImportHintEnabled()) return;
|
||||
if (!DaemonCodeAnalyzer.getInstance(myProject).isImportHintsEnabled(myFile)) return;
|
||||
if (!CodeInsightSettings.getInstance().ADD_UNAMBIGIOUS_IMPORTS_ON_THE_FLY) return;
|
||||
|
||||
Document document = getDocument();
|
||||
final List<HighlightInfo> infos = new ArrayList<HighlightInfo>();
|
||||
DaemonCodeAnalyzerImpl.processHighlights(document, myProject, null, 0, document.getTextLength(), new Processor<HighlightInfo>() {
|
||||
@Override
|
||||
public boolean process(HighlightInfo info) {
|
||||
if (!info.hasHint() || info.getSeverity() != HighlightSeverity.ERROR) {
|
||||
return true;
|
||||
}
|
||||
if (TextRange.create(info.getActualStartOffset(), info.getActualEndOffset()).containsOffset(caretOffset)) return true;
|
||||
infos.add(info);
|
||||
return true;
|
||||
}
|
||||
});
|
||||
|
||||
ReferenceImporter[] importers = Extensions.getExtensions(ReferenceImporter.EP_NAME);
|
||||
for (HighlightInfo info : infos) {
|
||||
for(ReferenceImporter importer: importers) {
|
||||
if (importer.autoImportReferenceAt(myEditor, myFile, info.getActualStartOffset())) break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@NotNull
|
||||
private static List<HighlightInfo> getVisibleHighlights(final int startOffset, final int endOffset, Project project, final Editor editor) {
|
||||
final List<HighlightInfo> highlights = new ArrayList<HighlightInfo>();
|
||||
|
||||
+4
-3
@@ -21,6 +21,7 @@ import com.intellij.openapi.util.Comparing;
|
||||
import com.intellij.psi.PsiElement;
|
||||
import com.intellij.psi.PsiFile;
|
||||
import com.intellij.psi.PsiMember;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
import org.jetbrains.plugins.groovy.lang.psi.GrReferenceElement;
|
||||
import org.jetbrains.plugins.groovy.lang.psi.GroovyFile;
|
||||
import org.jetbrains.plugins.groovy.lang.psi.api.toplevel.imports.GrImportStatement;
|
||||
@@ -35,17 +36,17 @@ public class GroovyAddImportAction extends ImportClassFixBase<GrReferenceElement
|
||||
}
|
||||
|
||||
@Override
|
||||
protected String getReferenceName(GrReferenceElement reference) {
|
||||
protected String getReferenceName(@NotNull GrReferenceElement reference) {
|
||||
return reference.getReferenceName();
|
||||
}
|
||||
|
||||
@Override
|
||||
protected PsiElement getReferenceNameElement(GrReferenceElement reference) {
|
||||
protected PsiElement getReferenceNameElement(@NotNull GrReferenceElement reference) {
|
||||
return reference.getReferenceNameElement();
|
||||
}
|
||||
|
||||
@Override
|
||||
protected boolean hasTypeParameters(GrReferenceElement reference) {
|
||||
protected boolean hasTypeParameters(@NotNull GrReferenceElement reference) {
|
||||
return reference.getTypeArguments().length > 0;
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user