private Pair<MutableTextRange, StringBuffer> getFragmentByRange(int start, final int length) {
      final StringBuffer fragmentBuffer = new StringBuffer();
      int end = start + length;

      // restoring buffer and remove all subfragments from the list
      int documentOffset = 0;
      int effectiveOffset = 0;

      Iterator<Pair<MutableTextRange, StringBuffer>> iterator = myAffectedFragments.iterator();
      while (iterator.hasNext() && effectiveOffset <= end) {
        final Pair<MutableTextRange, StringBuffer> pair = iterator.next();
        final MutableTextRange range = pair.getFirst();
        final StringBuffer buffer = pair.getSecond();
        int effectiveFragmentEnd = range.getStartOffset() + buffer.length();

        if (range.getStartOffset() <= start && effectiveFragmentEnd >= end) return pair;

        if (effectiveFragmentEnd >= start) {
          final int effectiveStart = Math.max(effectiveOffset, start);
          if (range.getStartOffset() > start) {
            fragmentBuffer.append(
                myDocument.getCharsSequence(),
                effectiveStart - effectiveOffset + documentOffset,
                Math.min(range.getStartOffset(), end) - effectiveOffset + documentOffset);
          }
          if (end >= range.getStartOffset()) {
            fragmentBuffer.append(buffer);
            end =
                end > effectiveFragmentEnd
                    ? end - (buffer.length() - range.getLength())
                    : range.getEndOffset();
            effectiveFragmentEnd = range.getEndOffset();
            start = Math.min(start, range.getStartOffset());
            iterator.remove();
          }
        }

        documentOffset += range.getEndOffset() - effectiveOffset;
        effectiveOffset = effectiveFragmentEnd;
      }

      if (effectiveOffset < end) {
        final int effectiveStart = Math.max(effectiveOffset, start);
        fragmentBuffer.append(
            myDocument.getCharsSequence(),
            effectiveStart - effectiveOffset + documentOffset,
            end - effectiveOffset + documentOffset);
      }

      MutableTextRange newRange = new MutableTextRange(start, end);
      final Pair<MutableTextRange, StringBuffer> pair =
          new Pair<MutableTextRange, StringBuffer>(newRange, fragmentBuffer);
      for (Pair<MutableTextRange, StringBuffer> affectedFragment : myAffectedFragments) {
        MutableTextRange range = affectedFragment.getFirst();
        assert end <= range.getStartOffset() || range.getEndOffset() <= start
            : "Range :" + range + "; Added: " + newRange;
      }
      myAffectedFragments.add(pair);
      return pair;
    }
  @Override
  @NotNull
  public String getPlainText() {
    int startOffset = getNavigationOffset();
    final PsiElement element = getElement();
    if (element != null && startOffset != -1) {
      final Document document = getDocument();
      if (document != null) {
        int lineNumber = document.getLineNumber(startOffset);
        int lineStart = document.getLineStartOffset(lineNumber);
        int lineEnd = document.getLineEndOffset(lineNumber);
        String prefixSuffix = null;

        if (lineEnd - lineStart > ChunkExtractor.MAX_LINE_LENGTH_TO_SHOW) {
          prefixSuffix = "...";
          lineStart =
              Math.max(
                  startOffset - ChunkExtractor.OFFSET_BEFORE_TO_SHOW_WHEN_LONG_LINE, lineStart);
          lineEnd =
              Math.min(startOffset + ChunkExtractor.OFFSET_AFTER_TO_SHOW_WHEN_LONG_LINE, lineEnd);
        }
        String s = document.getCharsSequence().subSequence(lineStart, lineEnd).toString();
        if (prefixSuffix != null) s = prefixSuffix + s + prefixSuffix;
        return s;
      }
    }
    return UsageViewBundle.message("node.invalid");
  }
Пример #3
0
 @NotNull
 private Dimension expandIfNecessary(@NotNull Dimension base) {
   if (base.width >= myMinWidth && base.height >= myMinHeight) {
     return base;
   }
   return new Dimension(Math.max(myMinWidth, base.width), Math.max(myMinHeight, base.height));
 }
Пример #4
0
 private static LineRange expandLineRangeToCoverPsiElements(
     final LineRange range, Editor editor, final PsiFile file) {
   Pair<PsiElement, PsiElement> psiRange = getElementRange(editor, file, range);
   if (psiRange == null) return null;
   final PsiElement parent =
       PsiTreeUtil.findCommonParent(psiRange.getFirst(), psiRange.getSecond());
   Pair<PsiElement, PsiElement> elementRange =
       getElementRange(parent, psiRange.getFirst(), psiRange.getSecond());
   if (elementRange == null) return null;
   int endOffset = elementRange.getSecond().getTextRange().getEndOffset();
   Document document = editor.getDocument();
   if (endOffset > document.getTextLength()) {
     LOG.assertTrue(!PsiDocumentManager.getInstance(file.getProject()).isUncommited(document));
     LOG.assertTrue(PsiDocumentManagerImpl.checkConsistency(file, document));
   }
   int endLine;
   if (endOffset == document.getTextLength()) {
     endLine = document.getLineCount();
   } else {
     endLine = editor.offsetToLogicalPosition(endOffset).line + 1;
     endLine = Math.min(endLine, document.getLineCount());
   }
   int startLine =
       Math.min(
           range.startLine,
           editor.offsetToLogicalPosition(elementRange.getFirst().getTextOffset()).line);
   endLine = Math.max(endLine, range.endLine);
   return new LineRange(startLine, endLine);
 }
Пример #5
0
  /**
   * Returns the original comment info of the specified element or null
   *
   * @param element the specified element
   * @return text chunk
   */
  @Nullable
  private static String getOrigCommentInfo(PsiDocCommentOwner element) {
    StringBuilder sb = new StringBuilder();
    PsiElement e = element.getFirstChild();
    if (!(e instanceof PsiComment)) {
      // no comments for this element
      return null;
    } else {
      boolean first = true;
      while (true) {
        if (e instanceof PsiDocComment) {
          PsiComment cm = (PsiComment) e;
          String text = cm.getText();
          if (text.startsWith("//")) {
            if (!first) sb.append('\n');
            sb.append(text.substring(2).trim());
          } else if (text.startsWith("/*")) {
            if (text.charAt(2) == '*') {
              text = text.substring(3, Math.max(3, text.length() - 2));
            } else {
              text = text.substring(2, Math.max(2, text.length() - 2));
            }
            sb.append(text);
          }
        } else if (!(e instanceof PsiWhiteSpace) && !(e instanceof PsiComment)) {
          break;
        }
        first = false;
        e = e.getNextSibling();
      }

      return sb.toString();
    }
  }
 int getNavigationOffset() {
   Document document = getDocument();
   if (document == null) return -1;
   int offset = getUsageInfo().getNavigationOffset();
   if (offset == -1) offset = myOffset;
   if (offset >= document.getTextLength()) {
     int line = Math.max(0, Math.min(myLineNumber, document.getLineCount() - 1));
     offset = document.getLineStartOffset(line);
   }
   return offset;
 }
Пример #7
0
 private void updatedMovedIntoEnd(
     final Document document, @NotNull final MoveInfo info, final int offset) {
   if (offset + 1 < document.getTextLength()) {
     final int line = document.getLineNumber(offset + 1);
     final LineRange toMove2 = info.toMove2;
     if (toMove2 == null) return;
     info.toMove2 =
         new LineRange(
             toMove2.startLine,
             Math.min(Math.max(line, toMove2.endLine), document.getLineCount() - 1));
   }
 }
Пример #8
0
 public static boolean filterEquals(ClassFilter[] filters1, ClassFilter[] filters2) {
   if (filters1.length != filters2.length) {
     return false;
   }
   final Set<ClassFilter> f1 =
       new HashSet<ClassFilter>(Math.max((int) (filters1.length / .75f) + 1, 16));
   final Set<ClassFilter> f2 =
       new HashSet<ClassFilter>(Math.max((int) (filters2.length / .75f) + 1, 16));
   Collections.addAll(f1, filters1);
   Collections.addAll(f2, filters2);
   return f2.equals(f1);
 }
 private boolean isWhiteSpaceOrComment(@NotNull PsiElement element, @NotNull TextRange range) {
   final TextRange textRange = element.getTextRange();
   TextRange intersection = range.intersection(textRange);
   if (intersection == null) {
     return false;
   }
   intersection =
       TextRange.create(
           Math.max(intersection.getStartOffset() - textRange.getStartOffset(), 0),
           Math.min(
               intersection.getEndOffset() - textRange.getStartOffset(), textRange.getLength()));
   return isWhiteSpaceOrComment(element)
       || intersection.substring(element.getText()).trim().length() == 0;
 }
Пример #10
0
  private static int calcMatch(final String expectedName, final List<String> words, int max) {
    if (expectedName == null) return max;

    String[] expectedWords = NameUtil.nameToWords(expectedName);
    int limit = Math.min(words.size(), expectedWords.length);
    for (int i = 0; i < limit; i++) {
      String word = words.get(words.size() - i - 1);
      String expectedWord = expectedWords[expectedWords.length - i - 1];
      if (word.equalsIgnoreCase(expectedWord)) {
        max = Math.max(max, i + 1);
      } else {
        break;
      }
    }
    return max;
  }
 public static boolean filterEquals(ClassFilter[] filters1, ClassFilter[] filters2) {
   if (filters1.length != filters2.length) {
     return false;
   }
   final Set<ClassFilter> f1 =
       new HashSet<ClassFilter>(Math.max((int) (filters1.length / .75f) + 1, 16));
   final Set<ClassFilter> f2 =
       new HashSet<ClassFilter>(Math.max((int) (filters2.length / .75f) + 1, 16));
   for (ClassFilter filter : filters1) {
     f1.add(filter);
   }
   for (ClassFilter aFilters2 : filters2) {
     f2.add(aFilters2);
   }
   return f2.equals(f1);
 }
  private static int getQuickFixType(PsiVariable variable) {
    PsiElement outerCodeBlock = PsiUtil.getVariableCodeBlock(variable, null);
    if (outerCodeBlock == null) return -1;
    List<PsiReferenceExpression> outerReferences = new ArrayList<PsiReferenceExpression>();
    collectReferences(outerCodeBlock, variable, outerReferences);

    int type = MAKE_FINAL;
    for (PsiReferenceExpression expression : outerReferences) {
      // if it happens that variable referenced from another inner class, make sure it can be make
      // final from there
      PsiClass innerClass =
          HighlightControlFlowUtil.getInnerClassVariableReferencedFrom(variable, expression);

      if (innerClass != null) {
        int thisType = MAKE_FINAL;
        if (writtenInside(variable, innerClass)) {
          // cannot make parameter array
          if (variable instanceof PsiParameter) return -1;
          thisType = MAKE_ARRAY;
        }
        if (thisType == MAKE_FINAL && !canBeFinal(variable, outerReferences)) {
          thisType = COPY_TO_FINAL;
        }
        type = Math.max(type, thisType);
      }
    }
    return type;
  }
  private static void logStats(Collection<PsiFile> otherFiles, long start) {
    long time = System.currentTimeMillis() - start;

    final Multiset<String> stats = HashMultiset.create();
    for (PsiFile file : otherFiles) {
      stats.add(
          StringUtil.notNullize(file.getViewProvider().getVirtualFile().getExtension())
              .toLowerCase());
    }

    List<String> extensions = ContainerUtil.newArrayList(stats.elementSet());
    Collections.sort(
        extensions,
        new Comparator<String>() {
          @Override
          public int compare(String o1, String o2) {
            return stats.count(o2) - stats.count(o1);
          }
        });

    String message =
        "Search in "
            + otherFiles.size()
            + " files with unknown types took "
            + time
            + "ms.\n"
            + "Mapping their extensions to an existing file type (e.g. Plain Text) might speed up the search.\n"
            + "Most frequent non-indexed file extensions: ";
    for (int i = 0; i < Math.min(10, extensions.size()); i++) {
      String extension = extensions.get(i);
      message += extension + "(" + stats.count(extension) + ") ";
    }
    LOG.info(message);
  }
  public static void initOffsets(final PsiFile file, final OffsetMap offsetMap) {
    int offset =
        Math.max(
            offsetMap.getOffset(CompletionInitializationContext.SELECTION_END_OFFSET),
            offsetMap.getOffset(CompletionInitializationContext.IDENTIFIER_END_OFFSET));

    PsiElement element = file.findElementAt(offset);
    if (element instanceof PsiWhiteSpace
        && (!element.textContains('\n')
            || CodeStyleSettingsManager.getSettings(file.getProject())
                .getCommonSettings(JavaLanguage.INSTANCE)
                .METHOD_PARAMETERS_LPAREN_ON_NEXT_LINE)) {
      element = file.findElementAt(element.getTextRange().getEndOffset());
    }
    if (element == null) return;

    if (LEFT_PAREN.accepts(element)) {
      offsetMap.addOffset(LPAREN_OFFSET, element.getTextRange().getStartOffset());
      PsiElement list = element.getParent();
      PsiElement last = list.getLastChild();
      if (last instanceof PsiJavaToken
          && ((PsiJavaToken) last).getTokenType() == JavaTokenType.RPARENTH) {
        offsetMap.addOffset(RPAREN_OFFSET, last.getTextRange().getStartOffset());
      }

      offsetMap.addOffset(ARG_LIST_END_OFFSET, list.getTextRange().getEndOffset());
    }
  }
 private void enterScope(PsiElement element) {
   scopeEntered.add(element);
   m_currentDepth++;
   if ((m_maximumDepth = Math.max(m_maximumDepth, m_currentDepth)) > myLimit) {
     stopWalking();
   }
 }
 private int getNamesMaxLength() {
   int len = 0;
   for (ParameterTableModelItemBase<ParameterInfoImpl> item : myParametersTableModel.getItems()) {
     final String text = item.parameter.getName();
     len = Math.max(len, text == null ? 0 : text.length());
   }
   return len;
 }
 @NotNull
 private static String toVfString(@NotNull Collection<VirtualFile> list) {
   List<VirtualFile> sub = new ArrayList<VirtualFile>(list).subList(0, Math.min(list.size(), 100));
   return list.size()
       + " files: "
       + StringUtil.join(sub, file -> file.getName(), ", ")
       + (list.size() == sub.size() ? "" : "...");
 }
 private int getTypesMaxLength() {
   int len = 0;
   for (ParameterTableModelItemBase<ParameterInfoImpl> item : myParametersTableModel.getItems()) {
     final String text = item.typeCodeFragment == null ? null : item.typeCodeFragment.getText();
     len = Math.max(len, text == null ? 0 : text.length());
   }
   return len;
 }
Пример #19
0
    QuickDocInfoPane(
        @NotNull PsiElement documentationAnchor,
        @NotNull PsiElement elementUnderMouse,
        @NotNull JComponent baseDocControl) {
      myBaseDocControl = baseDocControl;

      PresentationFactory presentationFactory = new PresentationFactory();
      for (AbstractDocumentationTooltipAction action : ourTooltipActions) {
        Icon icon = action.getTemplatePresentation().getIcon();
        Dimension minSize = new Dimension(icon.getIconWidth(), icon.getIconHeight());
        myButtons.add(
            new ActionButton(
                action,
                presentationFactory.getPresentation(action),
                IdeTooltipManager.IDE_TOOLTIP_PLACE,
                minSize));
        action.setDocInfo(documentationAnchor, elementUnderMouse);
      }
      Collections.reverse(myButtons);

      setPreferredSize(baseDocControl.getPreferredSize());
      setMaximumSize(baseDocControl.getMaximumSize());
      setMinimumSize(baseDocControl.getMinimumSize());
      setBackground(baseDocControl.getBackground());

      add(baseDocControl, Integer.valueOf(0));
      int minWidth = 0;
      int minHeight = 0;
      int buttonWidth = 0;
      for (JComponent button : myButtons) {
        button.setBorder(null);
        button.setBackground(baseDocControl.getBackground());
        add(button, Integer.valueOf(1));
        button.setVisible(false);
        Dimension preferredSize = button.getPreferredSize();
        minWidth += preferredSize.width;
        minHeight = Math.max(minHeight, preferredSize.height);
        buttonWidth = Math.max(buttonWidth, preferredSize.width);
      }
      myButtonWidth = buttonWidth;

      int margin = 2;
      myMinWidth = minWidth + margin * 2 + (myButtons.size() - 1) * BUTTON_HGAP;
      myMinHeight = minHeight + margin * 2;
    }
Пример #20
0
    @Override
    public void exchangeRows(int row, int targetRow) {
      if (row < 0 || row >= getVariableData().length) return;
      if (targetRow < 0 || targetRow >= getVariableData().length) return;

      final VariableData currentItem = getVariableData()[row];
      getVariableData()[row] = getVariableData()[targetRow];
      getVariableData()[targetRow] = currentItem;

      TypeSelector currentSelector = myParameterTypeSelectors[row];
      myParameterTypeSelectors[row] = myParameterTypeSelectors[targetRow];
      myParameterTypeSelectors[targetRow] = currentSelector;

      myTypeRendererCombo.setModel(new DefaultComboBoxModel(getVariableData()));

      myTableModel.fireTableRowsUpdated(Math.min(targetRow, row), Math.max(targetRow, row));
      myTable.getSelectionModel().setSelectionInterval(targetRow, targetRow);
      updateSignature();
    }
    private String getText(final int start, final int end) {
      int currentOldDocumentOffset = 0;
      int currentNewDocumentOffset = 0;
      StringBuilder text = new StringBuilder();
      Iterator<Pair<MutableTextRange, StringBuffer>> iterator = myAffectedFragments.iterator();
      while (iterator.hasNext() && currentNewDocumentOffset < end) {
        final Pair<MutableTextRange, StringBuffer> pair = iterator.next();
        final MutableTextRange range = pair.getFirst();
        final StringBuffer buffer = pair.getSecond();
        final int fragmentEndInNewDocument = range.getStartOffset() + buffer.length();

        if (range.getStartOffset() <= start && fragmentEndInNewDocument >= end) {
          return buffer.substring(start - range.getStartOffset(), end - range.getStartOffset());
        }

        if (range.getStartOffset() >= start) {
          final int effectiveStart = Math.max(currentNewDocumentOffset, start);
          text.append(
              myDocument.getCharsSequence(),
              effectiveStart - currentNewDocumentOffset + currentOldDocumentOffset,
              Math.min(range.getStartOffset(), end)
                  - currentNewDocumentOffset
                  + currentOldDocumentOffset);
          if (end > range.getStartOffset()) {
            text.append(
                buffer.substring(0, Math.min(end - range.getStartOffset(), buffer.length())));
          }
        }

        currentOldDocumentOffset += range.getEndOffset() - currentNewDocumentOffset;
        currentNewDocumentOffset = fragmentEndInNewDocument;
      }

      if (currentNewDocumentOffset < end) {
        final int effectiveStart = Math.max(currentNewDocumentOffset, start);
        text.append(
            myDocument.getCharsSequence(),
            effectiveStart - currentNewDocumentOffset + currentOldDocumentOffset,
            end - currentNewDocumentOffset + currentOldDocumentOffset);
      }

      return text.toString();
    }
 private void commitToOriginalInner() {
   final String text = myNewDocument.getText();
   final Map<
           PsiLanguageInjectionHost,
           Set<Trinity<RangeMarker, RangeMarker, SmartPsiElementPointer>>>
       map =
           ContainerUtil.classify(
               myMarkers.iterator(),
               new Convertor<
                   Trinity<RangeMarker, RangeMarker, SmartPsiElementPointer>,
                   PsiLanguageInjectionHost>() {
                 @Override
                 public PsiLanguageInjectionHost convert(
                     final Trinity<RangeMarker, RangeMarker, SmartPsiElementPointer> o) {
                   final PsiElement element = o.third.getElement();
                   return (PsiLanguageInjectionHost) element;
                 }
               });
   PsiDocumentManager documentManager = PsiDocumentManager.getInstance(myProject);
   documentManager.commitDocument(myOrigDocument); // commit here and after each manipulator update
   int localInsideFileCursor = 0;
   for (PsiLanguageInjectionHost host : map.keySet()) {
     if (host == null) continue;
     String hostText = host.getText();
     ProperTextRange insideHost = null;
     StringBuilder sb = new StringBuilder();
     for (Trinity<RangeMarker, RangeMarker, SmartPsiElementPointer> entry : map.get(host)) {
       RangeMarker origMarker = entry.first; // check for validity?
       int hostOffset = host.getTextRange().getStartOffset();
       ProperTextRange localInsideHost =
           new ProperTextRange(
               origMarker.getStartOffset() - hostOffset, origMarker.getEndOffset() - hostOffset);
       RangeMarker rangeMarker = entry.second;
       ProperTextRange localInsideFile =
           new ProperTextRange(
               Math.max(localInsideFileCursor, rangeMarker.getStartOffset()),
               rangeMarker.getEndOffset());
       if (insideHost != null) {
         // append unchanged inter-markers fragment
         sb.append(
             hostText.substring(insideHost.getEndOffset(), localInsideHost.getStartOffset()));
       }
       sb.append(
           localInsideFile.getEndOffset() <= text.length() && !localInsideFile.isEmpty()
               ? localInsideFile.substring(text)
               : "");
       localInsideFileCursor = localInsideFile.getEndOffset();
       insideHost = insideHost == null ? localInsideHost : insideHost.union(localInsideHost);
     }
     assert insideHost != null;
     ElementManipulators.getManipulator(host).handleContentChange(host, insideHost, sb.toString());
     documentManager.commitDocument(myOrigDocument);
   }
 }
Пример #23
0
  private int updateMovedRegionEnd(
      final Document document,
      int movedLineStart,
      final int valueStart,
      @NotNull final MoveInfo info,
      final boolean down) {
    final int line = document.getLineNumber(valueStart);
    final LineRange toMove = info.toMove;
    int delta = line - toMove.endLine;
    info.toMove = new LineRange(toMove.startLine, Math.max(line, toMove.endLine));

    // update moved range
    if (delta > 0 && down) {
      final LineRange toMove2 = info.toMove2;
      info.toMove2 =
          new LineRange(
              toMove2.startLine + delta,
              Math.min(toMove2.endLine + delta, document.getLineCount() - 1));
      movedLineStart = document.getLineStartOffset(toMove.startLine);
    }
    return movedLineStart;
  }
Пример #24
0
  private static void addNamesFromStatistics(
      Set<String> names,
      VariableKind variableKind,
      @Nullable String propertyName,
      @Nullable PsiType type) {
    String[] allNames =
        JavaStatisticsManager.getAllVariableNamesUsed(variableKind, propertyName, type);

    int maxFrequency = 0;
    for (String name : allNames) {
      int count =
          JavaStatisticsManager.getVariableNameUseCount(name, variableKind, propertyName, type);
      maxFrequency = Math.max(maxFrequency, count);
    }

    int frequencyLimit = Math.max(5, maxFrequency / 2);

    for (String name : allNames) {
      if (names.contains(name)) {
        continue;
      }
      int count =
          JavaStatisticsManager.getVariableNameUseCount(name, variableKind, propertyName, type);
      if (LOG.isDebugEnabled()) {
        LOG.debug("new name:" + name + " count:" + count);
        LOG.debug("frequencyLimit:" + frequencyLimit);
      }
      if (count >= frequencyLimit) {
        names.add(name);
      }
    }

    if (propertyName != null && type != null) {
      addNamesFromStatistics(names, variableKind, propertyName, null);
      addNamesFromStatistics(names, variableKind, null, type);
    }
  }
    private int psiToDocumentOffset(int offset) {
      for (Map.Entry<TextRange, CharSequence> entry : myAffectedFragments.entrySet()) {
        int lengthAfter = entry.getValue().length();
        TextRange range = entry.getKey();
        if (range.getStartOffset() + lengthAfter < offset) {
          offset += range.getLength() - lengthAfter;
          continue;
        }

        // for offsets inside replaced ranges, return the starts of the original affected fragments
        // in document
        return Math.min(range.getStartOffset(), offset);
      }
      return offset;
    }
 private static void adjustIndentationInRange(
     final PsiFile file,
     final Document document,
     final TextRange[] indents,
     final int indentAdjustment) {
   final CharSequence charsSequence = document.getCharsSequence();
   for (final TextRange indent : indents) {
     final String oldIndentStr =
         charsSequence.subSequence(indent.getStartOffset() + 1, indent.getEndOffset()).toString();
     final int oldIndent =
         IndentHelperImpl.getIndent(file.getProject(), file.getFileType(), oldIndentStr, true);
     final String newIndentStr =
         IndentHelperImpl.fillIndent(
             file.getProject(), file.getFileType(), Math.max(oldIndent + indentAdjustment, 0));
     document.replaceString(indent.getStartOffset() + 1, indent.getEndOffset(), newIndentStr);
   }
 }
Пример #27
0
  private int updatedMovedRegionStart(
      final Document document,
      int movedLineStart,
      final int offset,
      @NotNull final MoveInfo info,
      final boolean down) {
    final int line = document.getLineNumber(offset);
    final LineRange toMove = info.toMove;
    int delta = toMove.startLine - line;
    info.toMove = new LineRange(Math.min(line, toMove.startLine), toMove.endLine);

    // update moved range
    if (delta > 0 && !down) {
      final LineRange toMove2 = info.toMove2;
      info.toMove2 = new LineRange(toMove2.startLine - delta, toMove2.endLine - delta);
      movedLineStart = document.getLineStartOffset(toMove.startLine);
    }
    return movedLineStart;
  }
Пример #28
0
  /**
   * It's possible that we need to expand quick doc control's width in order to provide better
   * visual representation (see http://youtrack.jetbrains.com/issue/IDEA-101425). This method
   * calculates that width expand.
   *
   * @param buttonWidth icon button's width
   * @param updatedText text which will be should at the quick doc control
   * @return width increase to apply to the target quick doc control (zero if no additional width
   *     increase is required)
   */
  private static int calculateWidthIncrease(int buttonWidth, String updatedText) {
    int maxLineWidth = 0;
    TIntArrayList lineWidths = new TIntArrayList();
    for (String lineText : StringUtil.split(updatedText, "<br/>")) {
      String html = HintUtil.prepareHintText(lineText, HintUtil.getInformationHint());
      int width = new JLabel(html).getPreferredSize().width;
      maxLineWidth = Math.max(maxLineWidth, width);
      lineWidths.add(width);
    }

    if (!lineWidths.isEmpty()) {
      int firstLineAvailableTrailingWidth = maxLineWidth - lineWidths.get(0);
      if (firstLineAvailableTrailingWidth >= buttonWidth) {
        return 0;
      } else {
        return buttonWidth - firstLineAvailableTrailingWidth;
      }
    }
    return 0;
  }
 private void queueUnresolvedFilesSinceLastRestart() {
   PersistentFS fs = PersistentFS.getInstance();
   int maxId = FSRecords.getMaxId();
   TIntArrayList list = new TIntArrayList();
   for (int id = fileIsResolved.nextClearBit(1);
       id >= 0 && id < maxId;
       id = fileIsResolved.nextClearBit(id + 1)) {
     int nextSetBit = fileIsResolved.nextSetBit(id);
     int endOfRun = Math.min(maxId, nextSetBit == -1 ? maxId : nextSetBit);
     do {
       VirtualFile virtualFile = fs.findFileById(id);
       if (queueIfNeeded(virtualFile, myProject)) {
         list.add(id);
       } else {
         fileIsResolved.set(id);
       }
     } while (++id < endOfRun);
   }
   log("Initially added to resolve " + toVfString(list.toNativeArray()));
 }
  private static PsiStatement getAnchor(PsiExpression[] expressionOccurences) {
    PsiElement parent = expressionOccurences[0];
    int minOffset = expressionOccurences[0].getTextRange().getStartOffset();
    for (int i = 1; i < expressionOccurences.length; i++) {
      parent = PsiTreeUtil.findCommonParent(parent, expressionOccurences[i]);
      LOG.assertTrue(parent != null);
      minOffset = Math.min(minOffset, expressionOccurences[i].getTextRange().getStartOffset());
    }

    PsiCodeBlock block =
        (PsiCodeBlock)
            (parent instanceof PsiCodeBlock
                ? parent
                : PsiTreeUtil.getParentOfType(parent, PsiCodeBlock.class));
    LOG.assertTrue(block != null && block.getStatements().length > 0);
    PsiStatement[] statements = block.getStatements();
    for (int i = 1; i < statements.length; i++) {
      if (statements[i].getTextRange().getStartOffset() > minOffset) return statements[i - 1];
    }
    return statements[statements.length - 1];
  }