protected void completionFinished(
      final int offset1,
      final int offset2,
      final CompletionProgressIndicator indicator,
      final LookupElement[] items,
      boolean hasModifiers) {
    if (items.length == 0) {
      LookupManager.getInstance(indicator.getProject()).hideActiveLookup();
      indicator.handleEmptyLookup(true);
      checkNotSync(indicator, items);
      return;
    }

    LOG.assertTrue(!indicator.isRunning(), "running");
    LOG.assertTrue(!indicator.isCanceled(), "canceled");

    indicator.getLookup().refreshUi(true, false);
    final AutoCompletionDecision decision = shouldAutoComplete(indicator, items);
    if (decision == AutoCompletionDecision.SHOW_LOOKUP) {
      CompletionServiceImpl.setCompletionPhase(new CompletionPhase.ItemsCalculated(indicator));
      indicator.getLookup().setCalculating(false);
      indicator.showLookup();
    } else if (decision instanceof AutoCompletionDecision.InsertItem) {
      final Runnable restorePrefix = rememberDocumentState(indicator.getEditor());

      final LookupElement item = ((AutoCompletionDecision.InsertItem) decision).getElement();
      CommandProcessor.getInstance()
          .executeCommand(
              indicator.getProject(),
              new Runnable() {
                @Override
                public void run() {
                  indicator.setMergeCommand();
                  indicator.getLookup().finishLookup(Lookup.AUTO_INSERT_SELECT_CHAR, item);
                }
              },
              "Autocompletion",
              null);

      // the insert handler may have started a live template with completion
      if (CompletionService.getCompletionService().getCurrentCompletion() == null
          && !ApplicationManager.getApplication().isUnitTestMode()) {
        CompletionServiceImpl.setCompletionPhase(
            hasModifiers
                ? new CompletionPhase.InsertedSingleItem(indicator, restorePrefix)
                : CompletionPhase.NoCompletion);
      }
      checkNotSync(indicator, items);
    } else if (decision == AutoCompletionDecision.CLOSE_LOOKUP) {
      LookupManager.getInstance(indicator.getProject()).hideActiveLookup();
      checkNotSync(indicator, items);
    }
  }
  private void finishCompletionProcess(boolean disposeOffsetMap) {
    cancel();

    ApplicationManager.getApplication().assertIsDispatchThread();
    Disposer.dispose(myQueue);
    LookupManager.getInstance(getProject()).removePropertyChangeListener(myLookupManagerListener);

    CompletionProgressIndicator currentCompletion =
        CompletionServiceImpl.getCompletionService().getCurrentCompletion();
    LOG.assertTrue(currentCompletion == this, currentCompletion + "!=" + this);

    CompletionServiceImpl.assertPhase(
        CompletionPhase.BgCalculation.class,
        CompletionPhase.ItemsCalculated.class,
        CompletionPhase.Synchronous.class,
        CompletionPhase.CommittingDocuments.class);
    if (CompletionServiceImpl.getCompletionPhase() instanceof CompletionPhase.CommittingDocuments) {
      LOG.assertTrue(
          CompletionServiceImpl.getCompletionPhase().indicator != null,
          CompletionServiceImpl.getCompletionPhase());
      ((CompletionPhase.CommittingDocuments) CompletionServiceImpl.getCompletionPhase()).replaced =
          true;
    }
    CompletionServiceImpl.setCompletionPhase(CompletionPhase.NoCompletion);
    if (disposeOffsetMap) {
      disposeOffsetMaps();
    }
  }
  @NotNull
  private LookupImpl obtainLookup(Editor editor) {
    CompletionAssertions.checkEditorValid(editor);
    LookupImpl existing = (LookupImpl) LookupManager.getActiveLookup(editor);
    if (existing != null && existing.isCompletion()) {
      existing.markReused();
      if (!autopopup) {
        existing.setFocusDegree(LookupImpl.FocusDegree.FOCUSED);
      }
      return existing;
    }

    LookupImpl lookup =
        (LookupImpl)
            LookupManager.getInstance(editor.getProject())
                .createLookup(
                    editor, LookupElement.EMPTY_ARRAY, "", new LookupArranger.DefaultArranger());
    if (editor.isOneLineMode()) {
      lookup.setCancelOnClickOutside(true);
      lookup.setCancelOnOtherWindowOpen(true);
    }
    lookup.setFocusDegree(
        autopopup ? LookupImpl.FocusDegree.UNFOCUSED : LookupImpl.FocusDegree.FOCUSED);
    return lookup;
  }
 public boolean value(final Project project) {
   final Component focusedComponent = WindowManagerEx.getInstanceEx().getFocusedComponent(project);
   boolean fromQuickSearch =
       focusedComponent != null
           && focusedComponent.getParent() instanceof ChooseByNameBase.JPanelProvider;
   return !fromQuickSearch && LookupManager.getInstance(project).getActiveLookup() == null;
 }
  private void assertCompletionContains(
      String completionText, PsiElement context, String[] expectedItems, String[] disallowedItems) {
    SmaliCodeFragmentFactory codeFragmentFactory = new SmaliCodeFragmentFactory();
    JavaCodeFragment fragment =
        codeFragmentFactory.createCodeFragment(
            new TextWithImportsImpl(CodeFragmentKind.EXPRESSION, completionText),
            context,
            getProject());

    Editor editor = createEditor(fragment.getVirtualFile());
    editor.getCaretModel().moveToOffset(completionText.length());

    new CodeCompletionHandlerBase(CompletionType.BASIC).invokeCompletion(getProject(), editor);
    List<LookupElement> elements =
        LookupManager.getInstance(getProject()).getActiveLookup().getItems();

    HashSet expectedSet = Sets.newHashSet(expectedItems);
    HashSet disallowedSet = Sets.newHashSet(disallowedItems);

    for (LookupElement element : elements) {
      expectedSet.remove(element.toString());
      Assert.assertFalse(disallowedSet.contains(element.toString()));
    }

    Assert.assertTrue(expectedSet.size() == 0);
  }
  public ParameterInfoController(
      @NotNull Project project,
      @NotNull Editor editor,
      int lbraceOffset,
      @NotNull LightweightHint hint,
      @NotNull ParameterInfoHandler handler,
      @NotNull ShowParameterInfoHandler.BestLocationPointProvider provider) {
    myProject = project;
    myEditor = editor;
    myHandler = handler;
    myProvider = provider;
    myLbraceMarker = editor.getDocument().createRangeMarker(lbraceOffset, lbraceOffset);
    myHint = hint;
    myComponent = (ParameterInfoComponent) myHint.getComponent();

    List<ParameterInfoController> allControllers = getAllControllers(myEditor);
    allControllers.add(this);

    myEditorCaretListener =
        new CaretAdapter() {
          @Override
          public void caretPositionChanged(CaretEvent e) {
            myAlarm.cancelAllRequests();
            addAlarmRequest();
          }
        };
    myEditor.getCaretModel().addCaretListener(myEditorCaretListener);

    myEditor
        .getDocument()
        .addDocumentListener(
            new DocumentAdapter() {
              @Override
              public void documentChanged(DocumentEvent e) {
                myAlarm.cancelAllRequests();
                addAlarmRequest();
              }
            },
            this);

    PropertyChangeListener lookupListener =
        new PropertyChangeListener() {
          @Override
          public void propertyChange(PropertyChangeEvent evt) {
            if (LookupManager.PROP_ACTIVE_LOOKUP.equals(evt.getPropertyName())) {
              Lookup lookup = (Lookup) evt.getNewValue();
              if (lookup != null) {
                adjustPositionForLookup(lookup);
              }
            }
          }
        };
    LookupManager.getInstance(project).addPropertyChangeListener(lookupListener, this);

    updateComponent();
    if (myEditor instanceof EditorImpl) {
      Disposer.register(((EditorImpl) myEditor).getDisposable(), this);
    }
  }
  /** @return Point in layered pane coordinate system */
  static Pair<Point, Short> chooseBestHintPosition(
      Project project,
      Editor editor,
      int line,
      int col,
      LightweightHint hint,
      boolean awtTooltip,
      short preferredPosition) {
    HintManagerImpl hintManager = HintManagerImpl.getInstanceImpl();
    Dimension hintSize = hint.getComponent().getPreferredSize();
    JComponent editorComponent = editor.getComponent();
    JLayeredPane layeredPane = editorComponent.getRootPane().getLayeredPane();

    Point p1;
    Point p2;
    boolean isLookupShown = LookupManager.getInstance(project).getActiveLookup() != null;
    if (isLookupShown) {
      p1 = hintManager.getHintPosition(hint, editor, HintManager.UNDER);
      p2 = hintManager.getHintPosition(hint, editor, HintManager.ABOVE);
    } else {
      LogicalPosition pos = new LogicalPosition(line, col);
      p1 = HintManagerImpl.getHintPosition(hint, editor, pos, HintManager.UNDER);
      p2 = HintManagerImpl.getHintPosition(hint, editor, pos, HintManager.ABOVE);
    }

    if (!awtTooltip) {
      p1.x = Math.min(p1.x, layeredPane.getWidth() - hintSize.width);
      p1.x = Math.max(p1.x, 0);
      p2.x = Math.min(p2.x, layeredPane.getWidth() - hintSize.width);
      p2.x = Math.max(p2.x, 0);
    }

    boolean p1Ok = p1.y + hintSize.height < layeredPane.getHeight();
    boolean p2Ok = p2.y >= 0;

    if (isLookupShown) {
      if (p1Ok) return new Pair<Point, Short>(p1, HintManager.UNDER);
      if (p2Ok) return new Pair<Point, Short>(p2, HintManager.ABOVE);
    } else {
      if (preferredPosition != HintManager.DEFAULT) {
        if (preferredPosition == HintManager.ABOVE) {
          if (p2Ok) return new Pair<Point, Short>(p2, HintManager.ABOVE);
        } else if (preferredPosition == HintManager.UNDER) {
          if (p1Ok) return new Pair<Point, Short>(p1, HintManager.UNDER);
        }
      }

      if (p1Ok) return new Pair<Point, Short>(p1, HintManager.UNDER);
      if (p2Ok) return new Pair<Point, Short>(p2, HintManager.ABOVE);
    }

    int underSpace = layeredPane.getHeight() - p1.y;
    int aboveSpace = p2.y;
    return aboveSpace > underSpace
        ? new Pair<Point, Short>(new Point(p2.x, 0), HintManager.UNDER)
        : new Pair<Point, Short>(p1, HintManager.ABOVE);
  }
示例#8
0
  public static void doTearDown() throws Exception {
    UsefulTestCase.doPostponedFormatting(ourProject);

    LookupManager.getInstance(ourProject).hideActiveLookup();

    InspectionProfileManager.getInstance().deleteProfile(PROFILE);
    assertNotNull("Application components damaged", ProjectManager.getInstance());

    ApplicationManager.getApplication()
        .runWriteAction(
            new Runnable() {
              public void run() {
                try {
                  final VirtualFile[] children = ourSourceRoot.getChildren();
                  for (VirtualFile child : children) {
                    child.delete(this);
                  }
                } catch (IOException e) {
                  //noinspection CallToPrintStackTrace
                  e.printStackTrace();
                }
                FileDocumentManager manager = FileDocumentManager.getInstance();
                if (manager instanceof FileDocumentManagerImpl) {
                  ((FileDocumentManagerImpl) manager).dropAllUnsavedDocuments();
                }
              }
            });
    //    final Project[] openProjects = ProjectManagerEx.getInstanceEx().getOpenProjects();
    //    assertTrue(Arrays.asList(openProjects).contains(ourProject));
    assertFalse(PsiManager.getInstance(getProject()).isDisposed());
    if (!ourAssertionsInTestDetected) {
      if (IdeaLogger.ourErrorsOccurred != null) {
        throw IdeaLogger.ourErrorsOccurred;
      }
      // assertTrue("Logger errors occurred. ", IdeaLogger.ourErrorsOccurred == null);
    }
    ((PsiDocumentManagerImpl) PsiDocumentManager.getInstance(getProject()))
        .clearUncommitedDocuments();

    ((UndoManagerImpl) UndoManager.getGlobalInstance()).dropHistoryInTests();

    ProjectManagerEx.getInstanceEx().setCurrentTestProject(null);
    ourApplication.setDataProvider(null);
    ourTestCase = null;
    ((PsiManagerImpl) ourPsiManager).cleanupForNextTest();

    final Editor[] allEditors = EditorFactory.getInstance().getAllEditors();
    if (allEditors.length > 0) {
      for (Editor allEditor : allEditors) {
        EditorFactory.getInstance().releaseEditor(allEditor);
      }
      fail("Unreleased editors: " + allEditors.length);
    }
  }
  public CompletionProgressIndicator(
      final Editor editor,
      CompletionParameters parameters,
      CodeCompletionHandlerBase handler,
      Semaphore freezeSemaphore,
      final OffsetMap offsetMap,
      boolean hasModifiers) {
    myEditor = editor;
    myParameters = parameters;
    myHandler = handler;
    myFreezeSemaphore = freezeSemaphore;
    myOffsetMap = offsetMap;
    myLookup = (LookupImpl) parameters.getLookup();

    myLookup.setArranger(new CompletionLookupArranger(parameters, this));

    myLookup.addLookupListener(myLookupListener);
    myLookup.setCalculating(true);

    myLookupManagerListener =
        new PropertyChangeListener() {
          @Override
          public void propertyChange(PropertyChangeEvent evt) {
            if (evt.getNewValue() != null) {
              LOG.error(
                  "An attempt to change the lookup during completion, phase = "
                      + CompletionServiceImpl.getCompletionPhase());
            }
          }
        };
    LookupManager.getInstance(getProject()).addPropertyChangeListener(myLookupManagerListener);

    myQueue =
        new MergingUpdateQueue(
            "completion lookup progress", 200, true, myEditor.getContentComponent());
    myQueue.setPassThrough(false);

    ApplicationManager.getApplication().assertIsDispatchThread();
    addMapToDispose(offsetMap);

    if (ApplicationManager.getApplication().isUnitTestMode()) {
      return;
    }

    if (!myLookup.isShown()) {
      scheduleAdvertising();
    }

    if (hasModifiers) {
      trackModifiers();
    }
  }
  public void closeAndFinish(boolean hideLookup) {
    if (!myLookup.isLookupDisposed()) {
      Lookup lookup = LookupManager.getActiveLookup(myEditor);
      LOG.assertTrue(lookup == myLookup, "lookup changed: " + lookup + "; " + this);
    }
    myLookup.removeLookupListener(myLookupListener);
    finishCompletionProcess(true);
    CompletionServiceImpl.assertPhase(CompletionPhase.NoCompletion.getClass());

    if (hideLookup) {
      LookupManager.getInstance(getProject()).hideActiveLookup();
    }
  }
  private void process(
      @NotNull final Project project,
      @NotNull final Editor editor,
      @NotNull final PsiFile file,
      final int attempt)
      throws TooManyAttemptsException {
    if (attempt > MAX_ATTEMPTS) throw new TooManyAttemptsException();

    try {
      commit(editor);
      if (myFirstErrorOffset != Integer.MAX_VALUE) {
        editor.getCaretModel().moveToOffset(myFirstErrorOffset);
      }

      myFirstErrorOffset = Integer.MAX_VALUE;

      PsiElement atCaret = getStatementAtCaret(editor, file);
      if (atCaret == null) {
        if (myJavadocFixer.process(editor, file)) {
          return;
        }
        if (!new CommentBreakerEnterProcessor().doEnter(editor, file, false)) {
          plainEnter(editor);
        }
        return;
      }

      List<PsiElement> queue = new ArrayList<PsiElement>();
      collectAllElements(atCaret, queue, true);
      queue.add(atCaret);

      for (PsiElement psiElement : queue) {
        for (Fixer fixer : ourFixers) {
          fixer.apply(editor, this, psiElement);
          if (LookupManager.getInstance(project).getActiveLookup() != null) {
            return;
          }
          if (isUncommited(project) || !psiElement.isValid()) {
            moveCaretInsideBracesIfAny(editor, file);
            process(project, editor, file, attempt + 1);
            return;
          }
        }
      }

      doEnter(atCaret, editor);
    } catch (IncorrectOperationException e) {
      LOG.error(e);
    }
  }
  @Override
  public void execute(Editor editor, Caret caret, DataContext dataContext) {
    LookupImpl lookup = (LookupImpl) LookupManager.getActiveLookup(editor);
    if (lookup == null
        || !lookup.isAvailableToUser()
        || myRequireFocusedLookup && !lookup.isFocused()) {
      Project project = editor.getProject();
      if (project != null) {
        LookupManager.getInstance(project).hideActiveLookup();
      }
      myOriginalHandler.executeInCaretContext(editor, caret, dataContext);
      return;
    }

    lookup.markSelectionTouched();
    executeInLookup(lookup, dataContext, caret);
  }
  protected void process(
      @NotNull final Project project,
      @NotNull final Editor editor,
      @NotNull final PsiFile file,
      final int attempt)
      throws TooManyAttemptsException {
    FeatureUsageTracker.getInstance().triggerFeatureUsed("codeassists.complete.statement");
    if (attempt > MAX_ATTEMPTS) throw new TooManyAttemptsException();

    try {
      commit(editor);
      if (myFirstErrorOffset != Integer.MAX_VALUE) {
        editor.getCaretModel().moveToOffset(myFirstErrorOffset);
      }

      myFirstErrorOffset = Integer.MAX_VALUE;

      PsiElement atCaret = getStatementAtCaret(editor, file);
      if (atCaret == null) {
        return;
      }

      OrderedSet<PsiElement> queue = new OrderedSet<PsiElement>();
      collectAllElements(atCaret, queue, true);
      queue.add(atCaret);

      for (PsiElement psiElement : queue) {
        for (Fixer fixer : ourFixers) {
          fixer.apply(editor, this, psiElement);
          if (LookupManager.getInstance(project).getActiveLookup() != null) {
            return;
          }
          if (isUncommited(project) || !psiElement.isValid()) {
            moveCaretInsideBracesIfAny(editor, file);
            process(project, editor, file, attempt + 1);
            return;
          }
        }
      }

      doEnter(atCaret, file, editor);
    } catch (IncorrectOperationException e) {
      LOG.error(e);
    }
  }
    public void applyFix(@NotNull Project project, @NotNull ProblemDescriptor descriptor) {
      final Editor editor =
          PlatformDataKeys.EDITOR.getData(DataManager.getInstance().getDataContext());
      assert editor != null;
      final TextRange textRange = ((ProblemDescriptorImpl) descriptor).getTextRange();
      editor.getSelectionModel().setSelection(textRange.getStartOffset(), textRange.getEndOffset());

      final String word = editor.getSelectionModel().getSelectedText();

      if (word == null || StringUtil.isEmptyOrSpaces(word)) {
        return;
      }
      final List<LookupElement> items = new ArrayList<LookupElement>();
      for (String variant : myUnboundParams) {
        items.add(LookupElementBuilder.create(variant));
      }
      LookupManager.getInstance(project)
          .showLookup(editor, items.toArray(new LookupElement[items.size()]));
    }
  private void invokeCompletion(final ExpressionContext context) {
    final Project project = context.getProject();
    final Editor editor = context.getEditor();

    final PsiFile psiFile = editor != null ? PsiUtilBase.getPsiFileInEditor(editor, project) : null;
    Runnable runnable =
        () -> {
          if (project.isDisposed()
              || editor == null
              || editor.isDisposed()
              || psiFile == null
              || !psiFile.isValid()) return;

          // it's invokeLater, so another completion could have started
          if (CompletionServiceImpl.getCompletionService().getCurrentCompletion() != null) return;

          CommandProcessor.getInstance()
              .executeCommand(
                  project,
                  () -> {
                    // if we're in some completion's insert handler, make sure our new completion
                    // isn't treated as the second invocation
                    CompletionServiceImpl.setCompletionPhase(CompletionPhase.NoCompletion);

                    invokeCompletionHandler(project, editor);
                    Lookup lookup = LookupManager.getInstance(project).getActiveLookup();

                    if (lookup != null) {
                      lookup.addLookupListener(
                          new MyLookupListener(context, myCheckCompletionChar));
                    }
                  },
                  "",
                  null);
        };
    ApplicationManager.getApplication().invokeLater(runnable);
  }
  public void invoke(
      @NotNull Project project, @NotNull final Editor editor, @NotNull PsiFile file) {
    if (!CodeInsightUtilBase.prepareFileForWrite(file)) return;

    LookupManager.getInstance(project).hideActiveLookup();

    final CharSequence charsSequence = editor.getDocument().getCharsSequence();

    final CompletionData data = computeData(editor, charsSequence);
    String currentPrefix = data.myPrefix;

    final CompletionState completionState = getCompletionState(editor);

    String oldPrefix = completionState.oldPrefix;
    CompletionVariant lastProposedVariant = completionState.lastProposedVariant;

    if (lastProposedVariant == null
        || oldPrefix == null
        || !new CamelHumpMatcher(oldPrefix).prefixMatches(currentPrefix)
        || // oldPrefix.length() == 0 ||
        !currentPrefix.equals(lastProposedVariant.variant)) {
      // we are starting over
      oldPrefix = currentPrefix;
      completionState.oldPrefix = oldPrefix;
      lastProposedVariant = null;
    }

    CompletionVariant nextVariant =
        computeNextVariant(editor, oldPrefix, lastProposedVariant, data);
    if (nextVariant == null) return;

    int replacementEnd = data.startOffset + data.myWordUnderCursor.length();
    editor.getDocument().replaceString(data.startOffset, replacementEnd, nextVariant.variant);
    editor.getCaretModel().moveToOffset(data.startOffset + nextVariant.variant.length());
    completionState.lastProposedVariant = nextVariant;
    highlightWord(editor, nextVariant, project, data);
  }