Merge branch 'master' of git@git.labs.intellij.net:idea/community

This commit is contained in:
Eugene Kudelevsky
2011-01-25 22:56:30 +03:00
24 changed files with 583 additions and 241 deletions
@@ -509,6 +509,12 @@ public class JavaCompletionContributor extends CompletionContributor {
return;
}
final PsiJavaCodeReferenceElement ref = PsiTreeUtil.findElementOfClassAtOffset(file, context.getStartOffset(), PsiJavaCodeReferenceElement.class, false);
if (ref != null && !(ref instanceof PsiReferenceExpression)) {
context.setDummyIdentifier(CompletionInitializationContext.DUMMY_IDENTIFIER.trim() + ";");
return;
}
final PsiElement element = file.findElementAt(context.getStartOffset());
if (psiElement().inside(PsiAnnotation.class).accepts(element)) {
@@ -680,8 +680,8 @@ public class JavaCompletionUtil {
final Document document = context.getEditor().getDocument();
PsiDocumentManager.getInstance(project).commitDocument(document);
final PsiFile file = context.getFile();
final PsiReferenceExpression ref =
PsiTreeUtil.findElementOfClassAtOffset(file, context.getStartOffset(), PsiReferenceExpression.class, false);
final PsiJavaCodeReferenceElement ref =
PsiTreeUtil.findElementOfClassAtOffset(file, context.getStartOffset(), PsiJavaCodeReferenceElement.class, false);
if (ref != null) {
final PsiElement qualifier = ref.getQualifier();
if (qualifier != null) {
@@ -1001,11 +1001,11 @@ public class JavaCompletionUtil {
}
public static boolean hasAccessibleInnerClass(@NotNull PsiClass psiClass, @NotNull PsiElement position) {
final PsiClass[] inners = psiClass.getAllInnerClasses();
final PsiClass[] inners = psiClass.getInnerClasses();
if (inners.length > 0) {
PsiResolveHelper resolveHelper = JavaPsiFacade.getInstance(position.getProject()).getResolveHelper();
for (PsiClass inner : inners) {
if (resolveHelper.isAccessible(inner, position, null)) {
if (inner.hasModifierProperty(PsiModifier.STATIC) && resolveHelper.isAccessible(inner, position, null)) {
return true;
}
}
@@ -15,8 +15,10 @@
*/
package com.intellij.psi.util.proximity;
import com.intellij.psi.CommonClassNames;
import com.intellij.psi.PsiClass;
import com.intellij.psi.PsiElement;
import com.intellij.psi.PsiMethod;
import com.intellij.psi.util.ProximityLocation;
import org.jetbrains.annotations.NonNls;
import org.jetbrains.annotations.NotNull;
@@ -24,7 +26,7 @@ import org.jetbrains.annotations.NotNull;
/**
* @author peter
*/
public class KnownPackageWeigher extends ProximityWeigher {
public class KnownElementWeigher extends ProximityWeigher {
public Comparable weigh(@NotNull final PsiElement element, @NotNull final ProximityLocation location) {
if (element instanceof PsiClass) {
@@ -34,6 +36,15 @@ public class KnownPackageWeigher extends ProximityWeigher {
if (qname.startsWith("javax.")) return 1;
}
}
if (element instanceof PsiMethod) {
final PsiMethod method = (PsiMethod)element;
if ("finalize".equals(method.getName()) || "registerNatives".equals(method.getName())) {
final PsiClass containingClass = method.getContainingClass();
if (containingClass != null && CommonClassNames.JAVA_LANG_OBJECT.equals(containingClass.getQualifiedName())) {
return -1;
}
}
}
return 0;
}
}
@@ -10,7 +10,7 @@ class Xxx {
private Xxx(String x) {
}
class Yyy {
static class Yyy {
}
}
@@ -10,7 +10,7 @@ class Xxx {
private Xxx(String x) {
}
class Yyy {
static class Yyy {
}
}
@@ -0,0 +1,11 @@
class Foo {
{
Zzoo l = new Zz<caret>
}
}
class Zzoo {
void run();
class Impl implements Zzoo {}
}
@@ -0,0 +1,11 @@
class Foo {
{
Zzoo l = new Zzoo()<caret>
}
}
class Zzoo {
void run();
class Impl implements Zzoo {}
}
@@ -0,0 +1,37 @@
/*
* Copyright 2000-2011 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.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
import javax.swing.*;
import java.awt.*;
public class Bar {
static class CellWrapper {
public boolean isSeparator() {
return true;
}
}
static class MyRenderer extends DefaultListCellRenderer {
public Component getListCellRendererComponent(JList list, Object value, int index, boolean s, boolean focus) {
assert value instanceof CellWrapper;
value.is<caret><car>
}
}
}
@@ -0,0 +1,37 @@
/*
* Copyright 2000-2011 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.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
import javax.swing.*;
import java.awt.*;
public class Bar {
static class CellWrapper {
public boolean isSeparator() {
return true;
}
}
static class MyRenderer extends DefaultListCellRenderer {
public Component getListCellRendererComponent(JList list, Object value, int index, boolean s, boolean focus) {
assert value instanceof CellWrapper;
((CellWrapper) value).isSeparator()<caret><car>
}
}
}
@@ -0,0 +1,24 @@
import javax.swing.*;
import java.awt.*;
public class Bar {
static class CellWrapper {
public boolean isSeparator() {
return true;
}
}
static class MyRenderer extends DefaultListCellRenderer {
public Component getListCellRendererComponent(JList list, Object value, int index, boolean s, boolean focus) {
assert value instanceof CellWrapper;
value.is<caret>
mySelected = isSelected;
}
}
}
@@ -0,0 +1,24 @@
import javax.swing.*;
import java.awt.*;
public class Bar {
static class CellWrapper {
public boolean isSeparator() {
return true;
}
}
static class MyRenderer extends DefaultListCellRenderer {
public Component getListCellRendererComponent(JList list, Object value, int index, boolean s, boolean focus) {
assert value instanceof CellWrapper;
((CellWrapper) value).isSeparator()<caret>
mySelected = isSelected;
}
}
}
@@ -0,0 +1,7 @@
public class Bar {
{
fina<caret>x
}
}
@@ -17,8 +17,6 @@ package com.intellij.codeInsight.completion
import com.intellij.codeInsight.lookup.Lookup
import com.intellij.openapi.actionSystem.IdeActions
import com.intellij.openapi.application.ApplicationManager
import com.intellij.openapi.application.ModalityState
import com.intellij.openapi.command.CommandProcessor
/**
@@ -252,13 +250,13 @@ class JavaAutoPopupTest extends CompletionAutoPopupTestCase {
}
""")
type 'ite'
ApplicationManager.application.invokeAndWait({
myFixture.type 'r'
lookup.markReused()
lookup.currentItem = lookup.items[0]
CommandProcessor.instance.executeCommand project, ({lookup.finishLookup Lookup.NORMAL_SELECT_CHAR} as Runnable), null, null
edt {
myFixture.type 'r'
lookup.markReused()
lookup.currentItem = lookup.items[0]
CommandProcessor.instance.executeCommand project, ({lookup.finishLookup Lookup.NORMAL_SELECT_CHAR} as Runnable), null, null
} as Runnable, ModalityState.NON_MODAL)
}
myFixture.checkResult """
class A { Iterable iterable;
{ iterable<caret> }
@@ -273,14 +271,13 @@ class JavaAutoPopupTest extends CompletionAutoPopupTestCase {
}
""")
type 'ite'
ApplicationManager.application.invokeAndWait({
myFixture.type 'r'
lookup.markReused()
myFixture.type '\b\b'
lookup.currentItem = lookup.items[0]
CommandProcessor.instance.executeCommand project, ({lookup.finishLookup Lookup.NORMAL_SELECT_CHAR} as Runnable), null, null
} as Runnable, ModalityState.NON_MODAL)
edt {
myFixture.type 'r'
lookup.markReused()
myFixture.type '\b\b'
lookup.currentItem = lookup.items[0]
CommandProcessor.instance.executeCommand project, ({lookup.finishLookup Lookup.NORMAL_SELECT_CHAR} as Runnable), null, null
}
myFixture.checkResult """
class A { Iterable iterable;
{ iterable<caret> }
@@ -295,10 +292,7 @@ class JavaAutoPopupTest extends CompletionAutoPopupTestCase {
}
""")
type 'th'
ApplicationManager.application.invokeAndWait({
myFixture.type 'r'
myFixture.type '\t'
} as Runnable, ModalityState.NON_MODAL)
edt { myFixture.type 'r\t'}
myFixture.checkResult """
class A {
{ throw new <caret> }
@@ -306,4 +300,35 @@ class JavaAutoPopupTest extends CompletionAutoPopupTestCase {
"""
}
public void testTwoQuickRestartsAfterHiding() {
myFixture.configureByText("a.java", """
class A {
{ <caret> }
}
""")
edt { myFixture.type 'A' }
joinAlarm() // completion started
edt { assert lookup; myFixture.type 'IO' }
joinAlarm()
joinAlarm()
joinCompletion()
assert lookup
assert 'ArrayIndexOutOfBoundsException' in myFixture.lookupElementStrings
}
public void testTypingDuringExplicitCompletion() {
myFixture.configureByText("a.java", """
class A {
{ Runnable r = new <caret> }
}
""")
myFixture.complete CompletionType.SMART
edt { myFixture.type 'Thr' }
joinCompletion()
assert lookup
assert 'Thread' in myFixture.lookupElementStrings
}
}
@@ -138,7 +138,6 @@ public class NormalCompletionOrderingTest extends CompletionSortingTestCase {
assertEquals(1, ((PsiMethod)myItems[1].getObject()).getParameterList().getParametersCount());
assertEquals(2, ((PsiMethod)myItems[2].getObject()).getParameterList().getParametersCount());
}
public void testStatsForClassNameInExpression() throws Throwable {
final VirtualFile foo = getSourceRoot().createChildDirectory(this, "foo");
VfsUtil.saveText(foo.createChildData(this, "FooBar.java"), "package foo; public interface FooBar {}");
@@ -149,4 +148,8 @@ public class NormalCompletionOrderingTest extends CompletionSortingTestCase {
assertPreferredItems(0, "FooBee", "FooBar");
}
public void testDispreferFinalize() throws Throwable {
checkPreferredItems(0, "final", "finalize");
}
}
@@ -664,6 +664,8 @@ public class NormalCompletionTest extends LightFixtureCompletionTestCase {
public void testClassNameWithInner() throws Throwable { doTest() }
public void testClassNameWithInstanceInner() throws Throwable { doTest('\n') }
public void testDoubleFalse() throws Throwable {
configureByFile(getTestName(false) + ".java");
assertStringItems("false", "finalize");
@@ -785,6 +787,8 @@ public class NormalCompletionTest extends LightFixtureCompletionTestCase {
public void testCastTooComplexInstanceofedQualifier() throws Throwable { doAntiTest(); }
public void testDontCastInstanceofedQualifier() throws Throwable { doTest(); }
public void testQualifierCastingWithUnknownAssignments() throws Throwable { doTest(); }
public void testQualifierCastingBeforeLt() throws Throwable { doTest(); }
public void testWildcardsInLookup() throws Exception {
configure()
@@ -15,11 +15,11 @@
*/
package com.intellij.codeInsight.completion
import com.intellij.codeInsight.CodeInsightSettings
import com.intellij.codeInsight.editorActions.CompletionAutoPopupHandler
import com.intellij.codeInsight.lookup.LookupManager
import com.intellij.codeInsight.lookup.impl.LookupImpl
import com.intellij.openapi.application.ApplicationManager
import com.intellij.openapi.application.ModalityState
import com.intellij.testFramework.PlatformTestUtil
import com.intellij.testFramework.fixtures.LightCodeInsightFixtureTestCase
import com.intellij.util.ui.UIUtil
@@ -28,13 +28,7 @@ import com.intellij.util.ui.UIUtil
*/
abstract class CompletionAutoPopupTestCase extends LightCodeInsightFixtureTestCase {
@Override protected void setUp() {
UIUtil.invokeAndWaitIfNeeded(new Runnable(){
@Override
void run() {
superSetUp()
}
})
edt { superSetUp() }
CompletionAutoPopupHandler.ourTestingAutopopup = true
}
void superSetUp() {
@@ -46,28 +40,43 @@ abstract class CompletionAutoPopupTestCase extends LightCodeInsightFixtureTestCa
@Override protected void tearDown() {
CompletionAutoPopupHandler.ourTestingAutopopup = false
UIUtil.invokeAndWaitIfNeeded(new Runnable(){
@Override
void run() {
superTearDown()
}
})
edt { superTearDown() }
}
protected void doHighlighting() {
UIUtil.invokeAndWaitIfNeeded({ myFixture.doHighlighting() } as Runnable)
edt { myFixture.doHighlighting() }
}
void type(String s) {
for (i in 0..<s.size()) {
final c = s.charAt(i)
myFixture.type(c)
ApplicationManager.application.invokeAndWait({ } as Runnable, ModalityState.NON_MODAL) // for the autopopup handler's alarm, or the restartCompletion's invokeLater
ApplicationManager.application.invokeAndWait({ } as Runnable, ModalityState.NON_MODAL) // for invokeLater in CompletionProgressIndicator.stop()
joinAlarm() // for the autopopup handler's alarm, or the restartCompletion's invokeLater
joinCompletion()
}
}
protected void joinCompletion() {
for (j in 1..1000) {
def l = lookup
if (!l || !l.calculating) {
joinAlarm() // for invokeLater in CompletionProgressIndicator.stop()
return
}
Thread.sleep(10)
}
fail("Too long completion")
}
protected void joinAlarm() {
edt { PlatformTestUtil.waitForAlarm(CodeInsightSettings.instance.AUTO_LOOKUP_DELAY)}
}
protected void edt(Closure c) {
UIUtil.invokeAndWaitIfNeeded(c as Runnable)
}
@Override protected void runTest() {
runTestBare()
}
@@ -81,7 +90,7 @@ abstract class CompletionAutoPopupTestCase extends LightCodeInsightFixtureTestCa
}
LookupImpl getLookup() {
LookupManager.getActiveLookup(myFixture.getEditor())
(LookupImpl)LookupManager.getActiveLookup(myFixture.getEditor())
}
}
@@ -120,7 +120,18 @@ public class CodeCompletionHandlerBase implements CodeInsightActionHandler {
psiFile.putUserData(PsiFileEx.BATCH_REFERENCE_PROCESSING, Boolean.TRUE);
final CompletionProgressIndicator indicator = CompletionServiceImpl.getCompletionService().getCurrentCompletion();
CompletionProgressIndicator indicator = CompletionServiceImpl.getCompletionService().getCurrentCompletion();
if (indicator != null) {
indicator.closeAndFinish(false);
} else {
CompletionPhase phase = CompletionServiceImpl.getCompletionPhase();
if (phase instanceof CompletionPhase.ZombiePhase) {
indicator = ((CompletionPhase.ZombiePhase)phase).indicator;
}
}
CompletionServiceImpl.setCompletionPhase(CompletionPhase.NoCompletion);
if (indicator != null) {
boolean repeated = indicator.isRepeatedInvocation(myCompletionType, editor);
if (repeated && !indicator.isRunning() && (!isAutocompleteCommonPrefixOnInvocation() || indicator.fillInCommonPrefix(true))) {
@@ -130,8 +141,6 @@ public class CodeCompletionHandlerBase implements CodeInsightActionHandler {
if (repeated) {
time = Math.max(indicator.getParameters().getInvocationCount() + 1, 2);
indicator.restorePrefix();
} else {
indicator.closeAndFinish(false);
}
}
@@ -267,6 +276,8 @@ public class CodeCompletionHandlerBase implements CodeInsightActionHandler {
final LookupImpl lookup = obtainLookup(editor);
CompletionServiceImpl.setCompletionPhase(new CompletionPhase.Synchronous());
final Semaphore freezeSemaphore = new Semaphore();
freezeSemaphore.down();
final CompletionProgressIndicator indicator = new CompletionProgressIndicator(editor, parameters, this, freezeSemaphore,
@@ -274,7 +285,7 @@ public class CodeCompletionHandlerBase implements CodeInsightActionHandler {
final AtomicReference<LookupElement[]> data = startCompletionThread(parameters, indicator, initContext);
if (!invokedExplicitly && (!ApplicationManager.getApplication().isUnitTestMode() || CompletionAutoPopupHandler.ourTestingAutopopup)) {
if ((!invokedExplicitly && !ApplicationManager.getApplication().isUnitTestMode()) || CompletionAutoPopupHandler.ourTestingAutopopup) {
indicator.notifyBackgrounded();
return;
}
@@ -368,7 +379,7 @@ public class CodeCompletionHandlerBase implements CodeInsightActionHandler {
}
};
if (ApplicationManager.getApplication().isUnitTestMode()) {
if (ApplicationManager.getApplication().isUnitTestMode() && !CompletionAutoPopupHandler.ourTestingAutopopup) {
computeRunnable.run();
} else {
ApplicationManager.getApplication().executeOnPooledThread(computeRunnable);
@@ -467,12 +478,14 @@ public class CodeCompletionHandlerBase implements CodeInsightActionHandler {
final LookupElement[] items) {
if (items.length == 0) {
LookupManager.getInstance(indicator.getProject()).hideActiveLookup();
handleEmptyLookup(indicator.getProject(), indicator.getEditor(), indicator.getParameters(), indicator);
CompletionServiceImpl.setCompletionPhase(
handleEmptyLookup(indicator.getProject(), indicator.getEditor(), indicator.getParameters(), indicator));
return;
}
final AutoCompletionDecision decision = shouldAutoComplete(indicator, items);
if (decision == AutoCompletionDecision.SHOW_LOOKUP) {
CompletionServiceImpl.setCompletionPhase(new CompletionPhase.ItemsCalculated());
indicator.getLookup().setCalculating(false);
indicator.showLookup();
if (isAutocompleteCommonPrefixOnInvocation() && items.length > 1) {
@@ -488,10 +501,10 @@ public class CodeCompletionHandlerBase implements CodeInsightActionHandler {
handleSingleItem(offset2, indicator, items, item.getLookupString(), item);
// the insert handler may have started a live template with completion
if (CompletionService.getCompletionService().getCurrentCompletion() == null) {
indicator.liveAfterDeath(null);
} else {
LOG.assertTrue(!indicator.isZombie(), indicator);
if (CompletionService.getCompletionService().getCurrentCompletion() == null &&
!ApplicationManager.getApplication().isUnitTestMode()) {
CompletionServiceImpl.setCompletionPhase(new CompletionPhase.InsertedSingleItem(indicator));
assert indicator.getCompletionState().isWaitingAfterAutoInsertion();
}
}
}
@@ -591,22 +604,29 @@ public class CodeCompletionHandlerBase implements CodeInsightActionHandler {
return invokedExplicitly && CodeInsightSettings.getInstance().AUTOCOMPLETE_COMMON_PREFIX;
}
protected void handleEmptyLookup(Project project, Editor editor, final CompletionParameters parameters, final CompletionProgressIndicator indicator) {
if (ApplicationManager.getApplication().isUnitTestMode()) return;
protected CompletionPhase handleEmptyLookup(Project project, Editor editor, final CompletionParameters parameters, final CompletionProgressIndicator indicator) {
if (ApplicationManager.getApplication().isUnitTestMode()) return CompletionPhase.NoCompletion;
if (!invokedExplicitly) {
return;
return CompletionPhase.NoCompletion;
}
indicator.assertDisposed();
assert !indicator.isAutopopupCompletion();
final CompletionPhase[] result = {CompletionPhase.NoCompletion};
for (final CompletionContributor contributor : CompletionContributor.forParameters(parameters)) {
final String text = contributor.handleEmptyLookup(parameters, editor);
if (StringUtil.isNotEmpty(text)) {
final EditorHintListener listener = new EditorHintListener() {
public void hintShown(final Project project, final LightweightHint hint, final int flags) {
indicator.liveAfterDeath(hint);
if (!indicator.areModifiersChanged()) {
result[0] = new CompletionPhase.NoSuggestionsHint(hint, indicator);
CompletionServiceImpl.setCompletionPhase(result[0]);
}
}
};
final MessageBusConnection connection = project.getMessageBus().connect();
connection.subscribe(EditorHintListener.TOPIC, listener);
assert text != null;
HintManager.getInstance().showErrorHint(editor, text);
connection.disconnect();
break;
@@ -616,32 +636,36 @@ public class CodeCompletionHandlerBase implements CodeInsightActionHandler {
if (codeAnalyzer != null) {
codeAnalyzer.updateVisibleHighlighters(editor);
}
return result[0];
}
private static void lookupItemSelected(final CompletionProgressIndicator context, @NotNull final LookupElement item, final char completionChar,
private static void lookupItemSelected(final CompletionProgressIndicator indicator, @NotNull final LookupElement item, final char completionChar,
final List<LookupElement> items) {
if (context.getHandler().autopopup) {
if (indicator.getHandler().autopopup) {
FeatureUsageTracker.getInstance().triggerFeatureUsed(CodeCompletionFeatures.EDITING_COMPLETION_BASIC);
}
final Editor editor = context.getEditor();
final PsiFile file = context.getParameters().getOriginalFile();
final InsertionContext context1 = new InsertionContext(context.getOffsetMap(), completionChar, items.toArray(new LookupElement[items.size()]), file, editor);
final Editor editor = indicator.getEditor();
final PsiFile file = indicator.getParameters().getOriginalFile();
final InsertionContext context = new InsertionContext(indicator.getOffsetMap(), completionChar, items.toArray(new LookupElement[items.size()]), file, editor);
ApplicationManager.getApplication().runWriteAction(new Runnable() {
public void run() {
final int idEndOffset = context.getIdentifierEndOffset();
if (idEndOffset != context.getSelectionEndOffset() && CompletionUtil.isOverwrite(item, completionChar)) {
editor.getDocument().deleteString(context.getSelectionEndOffset(), idEndOffset);
final int idEndOffset = indicator.getIdentifierEndOffset();
if (idEndOffset != indicator.getSelectionEndOffset() && CompletionUtil.isOverwrite(item, completionChar)) {
editor.getDocument().deleteString(indicator.getSelectionEndOffset(), idEndOffset);
}
PsiDocumentManager.getInstance(context.getProject()).commitAllDocuments();
item.handleInsert(context1);
PostprocessReformattingAspect.getInstance(context.getProject()).doPostponedFormatting();
assert context.getStartOffset() >= 0 : "stale startOffset";
assert context.getTailOffset() >= 0 : "stale tailOffset";
PsiDocumentManager.getInstance(indicator.getProject()).commitAllDocuments();
item.handleInsert(context);
PostprocessReformattingAspect.getInstance(indicator.getProject()).doPostponedFormatting();
final int tailOffset = context1.getTailOffset();
final int tailOffset = context.getTailOffset();
if (tailOffset >= 0) {
if (context1.shouldAddCompletionChar() &&
if (context.shouldAddCompletionChar() &&
completionChar != Lookup.AUTO_INSERT_SELECT_CHAR && completionChar != Lookup.REPLACE_SELECT_CHAR &&
completionChar != Lookup.NORMAL_SELECT_CHAR && completionChar != Lookup.COMPLETE_STATEMENT_SELECT_CHAR) {
TailType.insertChar(editor, tailOffset, completionChar);
@@ -653,11 +677,11 @@ public class CodeCompletionHandlerBase implements CodeInsightActionHandler {
editor.getScrollingModel().scrollToCaret(ScrollType.RELATIVE);
}
});
final Runnable runnable = context1.getLaterRunnable();
final Runnable runnable = context.getLaterRunnable();
if (runnable != null) {
final Runnable runnable1 = new Runnable() {
public void run() {
final Project project = context1.getProject();
final Project project = context.getProject();
if (project.isDisposed()) return;
runnable.run();
}
@@ -0,0 +1,118 @@
/*
* Copyright 2000-2011 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.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package com.intellij.codeInsight.completion;
import com.intellij.codeInsight.completion.impl.CompletionServiceImpl;
import com.intellij.openapi.Disposable;
import com.intellij.openapi.editor.CaretModel;
import com.intellij.openapi.editor.Document;
import com.intellij.openapi.editor.Editor;
import com.intellij.openapi.editor.SelectionModel;
import com.intellij.openapi.editor.event.*;
import com.intellij.openapi.util.Disposer;
import com.intellij.ui.HintListener;
import com.intellij.ui.LightweightHint;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
import java.util.EventObject;
/**
* @author peter
*/
public abstract class CompletionPhase implements Disposable {
public static final CompletionPhase NoCompletion = new CompletionPhase() {};
@Override
public void dispose() {
}
public static class AutoPopupAlarm extends CompletionPhase {}
public static class Synchronous extends CompletionPhase {}
public static class BgCalculation extends CompletionPhase {}
public static class ItemsCalculated extends CompletionPhase {}
public static class Restarted extends CompletionPhase {}
public static class ZombiePhase extends CompletionPhase {
public final CompletionProgressIndicator indicator;
protected ZombiePhase(@Nullable final LightweightHint hint, final CompletionProgressIndicator indicator) {
this.indicator = indicator;
@NotNull Editor editor = indicator.getEditor();
final HintListener hintListener = new HintListener() {
public void hintHidden(final EventObject event) {
CompletionServiceImpl.setCompletionPhase(NoCompletion);
}
};
final DocumentAdapter documentListener = new DocumentAdapter() {
@Override
public void beforeDocumentChange(DocumentEvent e) {
CompletionServiceImpl.setCompletionPhase(NoCompletion);
}
};
final SelectionListener selectionListener = new SelectionListener() {
public void selectionChanged(SelectionEvent e) {
CompletionServiceImpl.setCompletionPhase(NoCompletion);
}
};
final CaretListener caretListener = new CaretListener() {
public void caretPositionChanged(CaretEvent e) {
CompletionServiceImpl.setCompletionPhase(NoCompletion);
}
};
final Document document = editor.getDocument();
final SelectionModel selectionModel = editor.getSelectionModel();
final CaretModel caretModel = editor.getCaretModel();
if (hint != null) {
hint.addHintListener(hintListener);
}
document.addDocumentListener(documentListener);
selectionModel.addSelectionListener(selectionListener);
caretModel.addCaretListener(caretListener);
Disposer.register(this, new Disposable() {
@Override
public void dispose() {
if (hint != null) {
hint.removeHintListener(hintListener);
hint.hide();
}
document.removeDocumentListener(documentListener);
selectionModel.removeSelectionListener(selectionListener);
caretModel.removeCaretListener(caretListener);
}
});
}
}
public static class InsertedSingleItem extends ZombiePhase {
public InsertedSingleItem(CompletionProgressIndicator indicator) {
super(null, indicator);
}
}
public static class NoSuggestionsHint extends ZombiePhase {
public NoSuggestionsHint(@Nullable LightweightHint hint, CompletionProgressIndicator indicator) {
super(hint, indicator);
}
}
public static class PossiblyDisturbingAutoPopup extends CompletionPhase {}
public static class EmptyAutoPopup extends CompletionPhase {}
}
@@ -25,11 +25,7 @@ import com.intellij.openapi.application.Result;
import com.intellij.openapi.command.CommandProcessor;
import com.intellij.openapi.command.WriteCommandAction;
import com.intellij.openapi.diagnostic.Logger;
import com.intellij.openapi.editor.CaretModel;
import com.intellij.openapi.editor.Document;
import com.intellij.openapi.editor.Editor;
import com.intellij.openapi.editor.SelectionModel;
import com.intellij.openapi.editor.event.*;
import com.intellij.openapi.editor.ex.DocumentEx;
import com.intellij.openapi.progress.ProcessCanceledException;
import com.intellij.openapi.progress.ProgressManager;
@@ -47,8 +43,6 @@ import com.intellij.psi.PsiFile;
import com.intellij.psi.PsiReference;
import com.intellij.psi.ReferenceRange;
import com.intellij.psi.util.PsiUtilBase;
import com.intellij.ui.HintListener;
import com.intellij.ui.LightweightHint;
import com.intellij.util.ObjectUtils;
import com.intellij.util.concurrency.Semaphore;
import com.intellij.util.containers.ContainerUtil;
@@ -62,7 +56,6 @@ import javax.swing.*;
import java.awt.event.KeyAdapter;
import java.awt.event.KeyEvent;
import java.util.Collections;
import java.util.EventObject;
import java.util.List;
import java.util.concurrent.CopyOnWriteArrayList;
@@ -146,6 +139,7 @@ public class CompletionProgressIndicator extends ProgressIndicatorBase implement
}
void notifyBackgrounded() {
CompletionServiceImpl.setCompletionPhase(new CompletionPhase.BgCalculation());
myState.setBackgrounded();
}
@@ -197,6 +191,10 @@ public class CompletionProgressIndicator extends ProgressIndicatorBase implement
}
}
public CompletionState getCompletionState() {
return myState;
}
private static int findReplacementOffset(int selectionEndOffset, PsiReference reference) {
final List<TextRange> ranges = ReferenceRange.getAbsoluteRanges(reference);
for (TextRange range : ranges) {
@@ -287,20 +285,20 @@ public class CompletionProgressIndicator extends ProgressIndicatorBase implement
private void processModifier(KeyEvent e) {
final int code = e.getKeyCode();
if (code == KeyEvent.VK_CONTROL || code == KeyEvent.VK_META || code == KeyEvent.VK_ALT || code == KeyEvent.VK_SHIFT) {
contentComponent.removeKeyListener(this);
myState.modifiersChanged();
if (myState.isWaitingAfterAutoInsertion()) {
unregisterItself(true);
myState.handleDeath();
CompletionProgressIndicator currentCompletion = CompletionServiceImpl.getCompletionService().getCurrentCompletion();
assert currentCompletion == null : currentCompletion;
CompletionServiceImpl.setCompletionPhase(CompletionPhase.NoCompletion);
}
contentComponent.removeKeyListener(this);
}
}
});
}
boolean isZombie() {
return myState.isZombie();
}
private void setMergeCommand() {
CommandProcessor.getInstance().setCurrentCommandGroupId(getCompletionCommandName());
}
@@ -321,63 +319,12 @@ public class CompletionProgressIndicator extends ProgressIndicatorBase implement
CompletionServiceImpl.getCompletionService().setCurrentCompletion(this);
}
public void liveAfterDeath(@Nullable final LightweightHint hint) {
void assertDisposed() {
myState.assertDisposed();
}
if (myState.areModifiersChanged() || ApplicationManager.getApplication().isUnitTestMode()) {
return;
}
registerItself();
final HintListener hintListener = new HintListener() {
public void hintHidden(final EventObject event) {
unregisterItself(true);
}
};
final DocumentAdapter documentListener = new DocumentAdapter() {
@Override
public void beforeDocumentChange(DocumentEvent e) {
unregisterItself(true);
}
};
final SelectionListener selectionListener = new SelectionListener() {
public void selectionChanged(SelectionEvent e) {
unregisterItself(true);
}
};
final CaretListener caretListener = new CaretListener() {
public void caretPositionChanged(CaretEvent e) {
unregisterItself(true);
}
};
final Document document = myEditor.getDocument();
final SelectionModel selectionModel = myEditor.getSelectionModel();
final CaretModel caretModel = myEditor.getCaretModel();
if (hint != null) {
hint.addHintListener(hintListener);
}
document.addDocumentListener(documentListener);
selectionModel.addSelectionListener(selectionListener);
caretModel.addCaretListener(caretListener);
myState.goZombie(hint, new Runnable() {
@Override
public void run() {
if (hint != null) {
hint.removeHintListener(hintListener);
}
document.removeDocumentListener(documentListener);
selectionModel.removeSelectionListener(selectionListener);
caretModel.removeCaretListener(caretListener);
}
});
boolean areModifiersChanged() {
return myState.areModifiersChanged();
}
public CodeCompletionHandlerBase getHandler() {
@@ -453,21 +400,15 @@ public class CompletionProgressIndicator extends ProgressIndicatorBase implement
public void closeAndFinish(boolean hideLookup) {
LOG.assertTrue(this == CompletionServiceImpl.getCompletionService().getCurrentCompletion());
if (myState.getCompletionHint() != null) {
myState.getCompletionHint().hide();
}
Lookup lookup = LookupManager.getActiveLookup(myEditor);
if (lookup != null) {
LOG.assertTrue(lookup == myLookup);
myLookup.removeLookupListener(myLookupListener);
finishCompletionProcess();
LOG.assertTrue(lookup == myLookup);
myLookup.removeLookupListener(myLookupListener);
finishCompletionProcess();
myState.assertDisposed();
CompletionServiceImpl.assertPhase(CompletionPhase.NoCompletion.getClass());
if (hideLookup) {
LookupManager.getInstance(getProject()).hideActiveLookup();
}
} else {
myState.assertDisposed();
if (hideLookup) {
LookupManager.getInstance(getProject()).hideActiveLookup();
}
}
@@ -479,7 +420,15 @@ public class CompletionProgressIndicator extends ProgressIndicatorBase implement
ApplicationManager.getApplication().assertIsDispatchThread();
Disposer.dispose(myQueue);
unregisterItself(false);
myState.handleDeath();
CompletionProgressIndicator currentCompletion = CompletionServiceImpl.getCompletionService().getCurrentCompletion();
assert currentCompletion == this : currentCompletion + "!=" + this;
CompletionServiceImpl.getCompletionService().setCurrentCompletion(null);
CompletionServiceImpl.assertPhase(CompletionPhase.BgCalculation.class, CompletionPhase.ItemsCalculated.class, CompletionPhase.Synchronous.class, CompletionPhase.Restarted.class);
CompletionServiceImpl.setCompletionPhase(CompletionPhase.NoCompletion);
}
@TestOnly
@@ -490,13 +439,6 @@ public class CompletionProgressIndicator extends ProgressIndicatorBase implement
}
}
private void unregisterItself(boolean afterDeath) {
myState.handleDeath(afterDeath);
CompletionProgressIndicator currentCompletion = CompletionServiceImpl.getCompletionService().getCurrentCompletion();
assert currentCompletion == this : currentCompletion + "!=" + this;
CompletionServiceImpl.getCompletionService().setCurrentCompletion(null);
}
public void stop() {
super.stop();
@@ -507,22 +449,32 @@ public class CompletionProgressIndicator extends ProgressIndicatorBase implement
public void run() {
if (isOutdated()) return;
if (!isBackgrounded()) return;
if (isCanceled() && !myState.isRestartScheduled()) return;
if (isCanceled() && myState.isRestartScheduled()) {
CompletionServiceImpl.assertPhase(CompletionPhase.Restarted.class);
return;
}
myLookup.setCalculating(false);
if (hideAutopopupIfMeaningless()) {
if (isCanceled()) {
CompletionServiceImpl.assertPhase(CompletionPhase.NoCompletion.getClass());
return;
}
if (CompletionServiceImpl.isPhase(CompletionPhase.BgCalculation.class) && hideAutopopupIfMeaningless()) {
return;
}
if (myState.hasNoVariants()) {
LookupManager.getInstance(getProject()).hideActiveLookup();
final CompletionProgressIndicator current = CompletionServiceImpl.getCompletionService().getCurrentCompletion();
LOG.assertTrue(current == null, current + "!=" + CompletionProgressIndicator.this);
if (!isAutopopupCompletion()) {
myHandler.handleEmptyLookup(getProject(), myEditor, myParameters, CompletionProgressIndicator.this);
LookupManager.getInstance(getProject()).hideActiveLookup();
final CompletionProgressIndicator current = CompletionServiceImpl.getCompletionService().getCurrentCompletion();
LOG.assertTrue(current == null, current + "!=" + CompletionProgressIndicator.this);
CompletionServiceImpl
.setCompletionPhase(myHandler.handleEmptyLookup(getProject(), myEditor, myParameters, CompletionProgressIndicator.this));
}
}
else {
@@ -530,6 +482,7 @@ public class CompletionProgressIndicator extends ProgressIndicatorBase implement
myLookup.setFocused(true);
}
updateLookup();
CompletionServiceImpl.setCompletionPhase(new CompletionPhase.ItemsCalculated());
}
}
}, myQueue.getModalityState());
@@ -542,6 +495,7 @@ public class CompletionProgressIndicator extends ProgressIndicatorBase implement
if (items.isEmpty() && !myLookup.isCalculating()) {
myLookup.hideLookup(false);
LOG.assertTrue(CompletionServiceImpl.getCompletionService().getCurrentCompletion() == null);
CompletionServiceImpl.setCompletionPhase(new CompletionPhase.EmptyAutoPopup());
return true;
}
@@ -549,6 +503,7 @@ public class CompletionProgressIndicator extends ProgressIndicatorBase implement
if ((item.getPrefixMatcher().getPrefix() + myLookup.getAdditionalPrefix()).equals(item.getLookupString())) {
myLookup.hideLookup(true); // so that the autopopup attempts to restart after the next typed character
LOG.assertTrue(CompletionServiceImpl.getCompletionService().getCurrentCompletion() == null);
CompletionServiceImpl.setCompletionPhase(new CompletionPhase.PossiblyDisturbingAutoPopup());
return true;
}
}
@@ -585,8 +540,6 @@ public class CompletionProgressIndicator extends ProgressIndicatorBase implement
}
public void restorePrefix() {
closeAndFinish(false);
new WriteCommandAction(getProject(), getCompletionCommandName()) {
@Override
protected void run(Result result) throws Throwable {
@@ -676,6 +629,8 @@ public class CompletionProgressIndicator extends ProgressIndicatorBase implement
public void scheduleRestart() {
ApplicationManager.getApplication().assertIsDispatchThread();
myState.scheduleRestart();
final CompletionPhase phase = new CompletionPhase.Restarted();
CompletionServiceImpl.setCompletionPhase(phase);
final Project project = getProject();
ApplicationManager.getApplication().invokeLater(new Runnable() {
@@ -684,6 +639,9 @@ public class CompletionProgressIndicator extends ProgressIndicatorBase implement
if (isOutdated()) {
return;
}
if (phase != CompletionServiceImpl.getCompletionPhase()) {
return;
}
closeAndFinish(false);
@@ -1,10 +1,8 @@
package com.intellij.codeInsight.completion;
import com.intellij.codeInsight.completion.impl.CompletionServiceImpl;
import com.intellij.openapi.application.ApplicationManager;
import com.intellij.openapi.diagnostic.Logger;
import com.intellij.ui.LightweightHint;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
/**
* @author peter
@@ -13,7 +11,6 @@ public class CompletionState {
private static final Logger LOG = Logger.getInstance("#com.intellij.codeInsight.completion.CompletionState");
private boolean myCompletionDisposed;
private boolean myShownLookup;
private LightweightHint myCompletionHint;
private Boolean myToRestart;
private boolean myRestartScheduled;
private boolean myModifiersChanged;
@@ -21,7 +18,6 @@ public class CompletionState {
private boolean myBackgrounded;
private volatile boolean myFocusLookupWhenDone;
private volatile int myCount;
private Runnable myZombieCleanup;
public CompletionState(boolean shownLookup) {
myShownLookup = shownLookup;
@@ -34,7 +30,6 @@ public class CompletionState {
public void setCompletionDisposed(boolean completionDisposed) {
LOG.assertTrue(!myCompletionDisposed, this);
LOG.assertTrue(!isWaitingAfterAutoInsertion(), this);
LOG.assertTrue(myCompletionHint == null, this);
myCompletionDisposed = completionDisposed;
}
@@ -46,21 +41,6 @@ public class CompletionState {
myShownLookup = shownLookup;
}
public LightweightHint getCompletionHint() {
return myCompletionHint;
}
public void goZombie(@Nullable LightweightHint completionHint, @NotNull Runnable cleanup) {
LOG.assertTrue(myZombieCleanup == null, this);
if (completionHint != null) {
LOG.assertTrue(myCompletionHint == null, this);
} else {
LOG.assertTrue(!myModifiersChanged, this);
}
myCompletionHint = completionHint;
myZombieCleanup = cleanup;
}
public boolean isToRestart() {
return myToRestart == Boolean.TRUE;
}
@@ -91,10 +71,16 @@ public class CompletionState {
}
public boolean isWaitingAfterAutoInsertion() {
return myRestorePrefix != null && isZombie();
CompletionPhase phase = CompletionServiceImpl.getCompletionPhase();
if (phase instanceof CompletionPhase.InsertedSingleItem && ((CompletionPhase.InsertedSingleItem)phase).indicator.getCompletionState() == this) {
LOG.assertTrue(myRestorePrefix != null, this);
return true;
}
return false;
}
public void setRestorePrefix(Runnable restorePrefix) {
CompletionServiceImpl.assertPhase(CompletionPhase.NoCompletion.getClass());
myRestorePrefix = restorePrefix;
}
@@ -121,27 +107,17 @@ public class CompletionState {
}
public void restorePrefix() {
CompletionServiceImpl.assertPhase(CompletionPhase.NoCompletion.getClass());
if (myRestorePrefix != null) {
myRestorePrefix.run();
myRestorePrefix = null;
}
}
public void handleDeath(boolean afterDeath) {
public void handleDeath() {
ApplicationManager.getApplication().assertIsDispatchThread();
boolean zombie = isZombie();
LOG.assertTrue(afterDeath == zombie, this);
assertDisposed();
if (zombie) {
myZombieCleanup.run();
}
myZombieCleanup = null;
myCompletionHint = null;
setRestorePrefix(null);
}
public boolean isZombie() {
return myZombieCleanup != null;
myRestorePrefix = null;
}
int incCount() {
@@ -155,9 +131,9 @@ public class CompletionState {
@Override
public String toString() {
return "CompletionState{" +
"myCompletionDisposed=" + myCompletionDisposed +
"phase=" + CompletionServiceImpl.getCompletionPhase() +
", myCompletionDisposed=" + myCompletionDisposed +
", myShownLookup=" + myShownLookup +
", myCompletionHint=" + myCompletionHint +
", myToRestart=" + myToRestart +
", myRestartScheduled=" + myRestartScheduled +
", myModifiersReleased=" + myModifiersChanged +
@@ -165,7 +141,6 @@ public class CompletionState {
", myBackgrounded=" + myBackgrounded +
", myFocusLookupWhenDone=" + myFocusLookupWhenDone +
", myCount=" + myCount +
", myZombieCleanup=" + myZombieCleanup +
'}';
}
}
@@ -20,10 +20,12 @@ import com.intellij.codeInsight.lookup.LookupElement;
import com.intellij.openapi.application.ApplicationManager;
import com.intellij.openapi.diagnostic.Logger;
import com.intellij.openapi.editor.Document;
import com.intellij.openapi.util.Disposer;
import com.intellij.openapi.util.text.StringUtil;
import com.intellij.patterns.ElementPattern;
import com.intellij.psi.PsiDocumentManager;
import com.intellij.psi.PsiElement;
import com.intellij.psi.impl.DebugUtil;
import com.intellij.util.Consumer;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
@@ -35,6 +37,8 @@ public class CompletionServiceImpl extends CompletionService{
private static final Logger LOG = Logger.getInstance("#com.intellij.codeInsight.completion.impl.CompletionServiceImpl");
private Throwable myTrace = null;
private CompletionProgressIndicator myCurrentCompletion;
private static CompletionPhase ourPhase = CompletionPhase.NoCompletion;
private static String ourPhaseTrace;
public static CompletionServiceImpl getCompletionService() {
return (CompletionServiceImpl)CompletionService.getCompletionService();
@@ -138,7 +142,13 @@ public class CompletionServiceImpl extends CompletionService{
final String newLookupString = handleCaseInsensitiveVariant(prefix, oldLookupString);
if (!newLookupString.equals(oldLookupString)) {
final Document document = context.getEditor().getDocument();
document.replaceString(context.getStartOffset(), context.getTailOffset(), newLookupString);
int startOffset = context.getStartOffset();
int tailOffset = context.getTailOffset();
assert startOffset >= 0 : "stale startOffset";
assert tailOffset >= 0 : "stale tailOffset";
document.replaceString(startOffset, tailOffset, newLookupString);
PsiDocumentManager.getInstance(context.getProject()).commitDocument(document);
}
}
@@ -162,4 +172,31 @@ public class CompletionServiceImpl extends CompletionService{
return lookupString;
}
public static void assertPhase(Class<? extends CompletionPhase>... possibilities) {
if (!isPhase(possibilities)) {
LOG.error(ourPhase + "; set at " + ourPhaseTrace);
}
}
public static boolean isPhase(Class<? extends CompletionPhase>... possibilities) {
ApplicationManager.getApplication().assertIsDispatchThread();
for (Class<? extends CompletionPhase> possibility : possibilities) {
if (possibility.isInstance(ourPhase)) {
return true;
}
}
return false;
}
public static void setCompletionPhase(@NotNull CompletionPhase phase) {
ApplicationManager.getApplication().assertIsDispatchThread();
Disposer.dispose(ourPhase);
ourPhase = phase;
ourPhaseTrace = DebugUtil.currentStackTrace();
}
public static CompletionPhase getCompletionPhase() {
// ApplicationManager.getApplication().assertIsDispatchThread();
return ourPhase;
}
}
@@ -18,6 +18,7 @@ package com.intellij.codeInsight.editorActions;
import com.intellij.codeInsight.AutoPopupController;
import com.intellij.codeInsight.CodeInsightSettings;
import com.intellij.codeInsight.completion.CodeCompletionHandlerBase;
import com.intellij.codeInsight.completion.CompletionPhase;
import com.intellij.codeInsight.completion.CompletionProgressIndicator;
import com.intellij.codeInsight.completion.CompletionType;
import com.intellij.codeInsight.completion.impl.CompletionServiceImpl;
@@ -93,9 +94,14 @@ public class CompletionAutoPopupHandler extends TypedHandlerDelegate {
final boolean isMainEditor = FileEditorManager.getInstance(project).getSelectedTextEditor() == editor;
final CompletionPhase.AutoPopupAlarm phase = new CompletionPhase.AutoPopupAlarm();
CompletionServiceImpl.setCompletionPhase(phase);
final Runnable request = new Runnable() {
@Override
public void run() {
if (CompletionServiceImpl.getCompletionPhase() != phase) return;
if (project.isDisposed() || !file.isValid()) return;
if (editor.isDisposed() || isMainEditor && FileEditorManager.getInstance(project).getSelectedTextEditor() != editor) return;
if (ApplicationManager.getApplication().isWriteAccessAllowed()) return; //it will fail anyway
@@ -152,9 +158,16 @@ public class CompletionAutoPopupHandler extends TypedHandlerDelegate {
}
final CompletionProgressIndicator currentCompletion = CompletionServiceImpl.getCompletionService().getCurrentCompletion();
if (currentCompletion != null) {
currentCompletion.closeAndFinish(true);
if (CompletionServiceImpl.isPhase(CompletionPhase.AutoPopupAlarm.class, CompletionPhase.EmptyAutoPopup.class, CompletionPhase.PossiblyDisturbingAutoPopup.class)) {
CompletionServiceImpl.setCompletionPhase(CompletionPhase.NoCompletion);
assert currentCompletion == null;
} else {
if (currentCompletion != null) {
currentCompletion.closeAndFinish(true);
}
CompletionServiceImpl.assertPhase(CompletionPhase.NoCompletion.getClass());
}
state.stopAutoPopup();
}
@@ -54,6 +54,7 @@ import com.intellij.openapi.actionSystem.Presentation;
import com.intellij.openapi.application.ApplicationManager;
import com.intellij.openapi.application.ModalityState;
import com.intellij.openapi.application.Result;
import com.intellij.openapi.command.CommandProcessor;
import com.intellij.openapi.command.WriteCommandAction;
import com.intellij.openapi.editor.*;
import com.intellij.openapi.editor.actionSystem.EditorActionHandler;
@@ -839,35 +840,42 @@ public class CodeInsightTestFixtureImpl extends BaseFixture implements CodeInsig
public LookupElement[] complete(final CompletionType type, final int invocationCount) {
assertInitialized();
myEmptyLookup = false;
new WriteCommandAction(getProject()) {
UIUtil.invokeAndWaitIfNeeded(new Runnable() {
@Override
protected void run(Result result) throws Exception {
final CodeCompletionHandlerBase handler = new CodeCompletionHandlerBase(type) {
public void run() {
CommandProcessor.getInstance().executeCommand(getProject(), new Runnable() {
@Override
protected PsiFile createFileCopy(final PsiFile file) {
final PsiFile copy = super.createFileCopy(file);
if (myFileContext != null) {
final PsiElement contextCopy = myFileContext.copy();
final PsiFile containingFile = contextCopy.getContainingFile();
if (containingFile instanceof PsiFileImpl) {
((PsiFileImpl)containingFile).setOriginalFile(myFileContext.getContainingFile());
public void run() {
final CodeCompletionHandlerBase handler = new CodeCompletionHandlerBase(type) {
@Override
protected PsiFile createFileCopy(final PsiFile file) {
final PsiFile copy = super.createFileCopy(file);
if (myFileContext != null) {
final PsiElement contextCopy = myFileContext.copy();
final PsiFile containingFile = contextCopy.getContainingFile();
if (containingFile instanceof PsiFileImpl) {
((PsiFileImpl)containingFile).setOriginalFile(myFileContext.getContainingFile());
}
setContext(copy, contextCopy);
}
return copy;
}
setContext(copy, contextCopy);
}
return copy;
}
@Override
protected void completionFinished(final int offset1, final int offset2, final CompletionProgressIndicator indicator,
final LookupElement[] items) {
myEmptyLookup = items.length == 0;
super.completionFinished(offset1, offset2, indicator, items);
@Override
protected void completionFinished(final int offset1, final int offset2, final CompletionProgressIndicator indicator,
final LookupElement[] items) {
myEmptyLookup = items.length == 0;
super.completionFinished(offset1, offset2, indicator, items);
}
};
Editor editor = getCompletionEditor();
handler.invokeCompletion(getProject(), editor, PsiUtilBase.getPsiFileInEditor(editor, getProject()), invocationCount);
}
};
Editor editor = getCompletionEditor();
handler.invokeCompletion(getProject(), editor, PsiUtilBase.getPsiFileInEditor(editor, getProject()), invocationCount);
}, null, null);
}
}.execute();
});
return getLookupElements();
}
+1 -1
View File
@@ -781,7 +781,7 @@
order="before openedInEditor"/>
<weigher key="proximity" implementationClass="com.intellij.psi.util.proximity.JavaInheritanceWeigher" id="javaInheritance"
order="after explicitlyImported, before sameLogicalRoot"/>
<weigher key="proximity" implementationClass="com.intellij.psi.util.proximity.KnownPackageWeigher" id="knownPackage"
<weigher key="proximity" implementationClass="com.intellij.psi.util.proximity.KnownElementWeigher" id="knownElement"
order="after sameModule, before sdkOrLibrary"/>
<statistician key="proximity" implementationClass="com.intellij.codeInsight.completion.JavaProximityStatistician"/>