예제 #1
0
  public TextRange getRangeInElement() {
    if (isSingleWord()) {
      return TextRange.from(0, getReferencedName().length());
    }

    return TextRange.from(1, getReferencedName().length()); // fixme make sure it has the end } ?
  }
예제 #2
0
  public TextRange getRangeInElement() {
    final PsiElement element = commandElement();
    if (element == null) {
      return TextRange.from(0, getTextLength());
    }

    return TextRange.from(element.getStartOffsetInParent(), element.getTextLength());
  }
예제 #3
0
 public void testPreferCapsMatching() {
   String sample = "getCurrentUser";
   //               0   4     10
   assertOrderedEquals(
       new MinusculeMatcher("getCU", NameUtil.MatchingCaseSensitivity.NONE)
           .matchingFragments(sample),
       TextRange.from(0, 4),
       TextRange.from(10, 1));
 }
예제 #4
0
 public void testMatchingFragmentsSorted() {
   @NonNls String sample = "SWUPGRADEHDLRFSPR7TEST";
   //                       0        9  12
   assertOrderedEquals(
       new MinusculeMatcher("SWU*H*R", NameUtil.MatchingCaseSensitivity.NONE)
           .matchingFragments(sample),
       TextRange.from(0, 3),
       TextRange.from(9, 1),
       TextRange.from(12, 1));
 }
 private static FList<TextRange> prependRange(
     @NotNull FList<TextRange> ranges, int from, int length) {
   TextRange head = ranges.getHead();
   if (head != null && head.getStartOffset() == from + length) {
     return ranges.getTail().prepend(new TextRange(from, head.getEndOffset()));
   }
   return ranges.prepend(TextRange.from(from, length));
 }
 @Override
 public TextRange getRangeInElement() {
   final PsiElement element = getSeparator();
   final int length = getTextLength();
   return element == null
       ? TextRange.from(0, length)
       : new TextRange(element.getStartOffsetInParent() + element.getTextLength(), length);
 }
예제 #7
0
 private SchemaPrefixReference createPrefixReference(
     ASTNode startTagName, String prefix, TagNameReference tagRef) {
   return new SchemaPrefixReference(
       this,
       TextRange.from(startTagName.getStartOffset() - getStartOffset(), prefix.length()),
       prefix,
       tagRef);
 }
예제 #8
0
  @Nullable("null means the file is clean")
  public static TextRange getDirtyTextRange(@NotNull Editor editor, int passId) {
    Document document = editor.getDocument();

    FileStatusMap me = DaemonCodeAnalyzerEx.getInstanceEx(editor.getProject()).getFileStatusMap();
    TextRange dirtyScope = me.getFileDirtyScope(document, passId);
    if (dirtyScope == null) return null;
    TextRange documentRange = TextRange.from(0, document.getTextLength());
    return documentRange.intersection(dirtyScope);
  }
예제 #9
0
  @NotNull
  public static PsiReference[] getReferences(BnfListEntry o) {
    BnfAttr attr = PsiTreeUtil.getParentOfType(o, BnfAttr.class);
    if (attr == null || !Comparing.equal(KnownAttribute.METHODS.getName(), attr.getName()))
      return PsiReference.EMPTY_ARRAY;
    PsiElement id = o.getId();
    BnfLiteralExpression value = o.getLiteralExpression();
    if (id == null || value != null) return PsiReference.EMPTY_ARRAY;
    final String psiImplUtilClass = getRootAttribute(attr, KnownAttribute.PSI_IMPL_UTIL_CLASS);
    final JavaHelper javaHelper = JavaHelper.getJavaHelper(o);

    return new PsiReference[] {
      new PsiPolyVariantReferenceBase<BnfListEntry>(
          o, TextRange.from(id.getStartOffsetInParent(), id.getTextLength())) {

        private List<NavigatablePsiElement> getTargetMethods(String methodName) {
          BnfRule rule = PsiTreeUtil.getParentOfType(getElement(), BnfRule.class);
          String mixinClass = rule == null ? null : getAttribute(rule, KnownAttribute.MIXIN);
          List<NavigatablePsiElement> implMethods =
              findRuleImplMethods(javaHelper, psiImplUtilClass, methodName, rule);
          if (!implMethods.isEmpty()) return implMethods;
          List<NavigatablePsiElement> mixinMethods =
              javaHelper.findClassMethods(
                  mixinClass, JavaHelper.MethodType.INSTANCE, methodName, -1);
          return ContainerUtil.concat(implMethods, mixinMethods);
        }

        @NotNull
        @Override
        public ResolveResult[] multiResolve(boolean b) {
          return PsiElementResolveResult.createResults(getTargetMethods(getElement().getText()));
        }

        @NotNull
        @Override
        public Object[] getVariants() {
          List<LookupElement> list = ContainerUtil.newArrayList();
          for (NavigatablePsiElement element : getTargetMethods("*")) {
            list.add(LookupElementBuilder.createWithIcon((PsiNamedElement) element));
          }
          return ArrayUtil.toObjectArray(list);
        }

        @Override
        public PsiElement handleElementRename(String newElementName)
            throws IncorrectOperationException {
          BnfListEntry element = getElement();
          PsiElement id = ObjectUtils.assertNotNull(element.getId());
          id.replace(BnfElementFactory.createLeafFromText(element.getProject(), newElementName));
          return element;
        }
      }
    };
  }
 private static void replaceElements(XmlTag tag, TemplateBuilder builder) {
   for (XmlAttribute attribute : tag.getAttributes()) {
     XmlAttributeValue value = attribute.getValueElement();
     if (value != null) {
       builder.replaceElement(value, TextRange.from(1, 0), new MacroCallNode(new CompleteMacro()));
     }
   }
   if ("<".equals(tag.getText())) {
     builder.replaceElement(
         tag, TextRange.from(1, 0), new MacroCallNode(new CompleteSmartMacro()));
   } else if (tag.getSubTags().length == 0) {
     int i = tag.getText().indexOf("></");
     if (i > 0) {
       builder.replaceElement(
           tag, TextRange.from(i + 1, 0), new MacroCallNode(new CompleteMacro()));
     }
   }
   for (XmlTag subTag : tag.getSubTags()) {
     replaceElements(subTag, builder);
   }
 }
 private static int appendRange(List<TextRange> result, int start, int length) {
   if (length > 0) {
     int lastIndex = result.size() - 1;
     TextRange lastRange = lastIndex >= 0 ? result.get(lastIndex) : null;
     if (lastRange != null && lastRange.getEndOffset() == start) {
       result.set(lastIndex, lastRange.grown(length));
     } else {
       result.add(TextRange.from(start, length));
     }
   }
   return start + length;
 }
  private void doReplaceString(int startOffset, int endOffset, CharSequence s) {
    assert intersectWithEditable(new TextRange(startOffset, startOffset)) != null;
    assert intersectWithEditable(new TextRange(endOffset, endOffset)) != null;

    List<Pair<TextRange, CharSequence>> hostRangesToModify;
    synchronized (myLock) {
      hostRangesToModify = new ArrayList<Pair<TextRange, CharSequence>>(myShreds.size());

      int offset = startOffset;
      int curRangeStart = 0;
      for (int i = 0; i < myShreds.size(); i++) {
        PsiLanguageInjectionHost.Shred shred = myShreds.get(i);
        curRangeStart += shred.getPrefix().length();
        if (offset < curRangeStart) offset = curRangeStart;
        Segment hostRange = shred.getHostRangeMarker();
        if (hostRange == null) continue;
        int hostRangeLength = hostRange.getEndOffset() - hostRange.getStartOffset();
        TextRange range = TextRange.from(curRangeStart, hostRangeLength);
        if (range.contains(offset)
            || range.getEndOffset() == offset /* in case of inserting at the end*/) {
          TextRange rangeToModify =
              new TextRange(offset, Math.min(range.getEndOffset(), endOffset));
          TextRange hostRangeToModify =
              rangeToModify.shiftRight(hostRange.getStartOffset() - curRangeStart);
          CharSequence toReplace =
              i == myShreds.size() - 1
                      || range.getEndOffset() + shred.getSuffix().length() >= endOffset
                  ? s
                  : s.subSequence(0, Math.min(hostRangeToModify.getLength(), s.length()));
          s = toReplace == s ? "" : s.subSequence(toReplace.length(), s.length());
          hostRangesToModify.add(Pair.create(hostRangeToModify, toReplace));
          offset = rangeToModify.getEndOffset();
        }
        curRangeStart += hostRangeLength;
        curRangeStart += shred.getSuffix().length();
        if (curRangeStart > endOffset) break;
      }
    }

    int delta = 0;
    for (Pair<TextRange, CharSequence> pair : hostRangesToModify) {
      TextRange hostRange = pair.getFirst();
      CharSequence replace = pair.getSecond();

      myDelegate.replaceString(
          hostRange.getStartOffset() + delta, hostRange.getEndOffset() + delta, replace);
      delta -= hostRange.getLength() - replace.length();
    }
  }
 /**
  * intersection may spread over several injected fragments
  *
  * @param rangeToEdit range in encoded(raw) PSI
  * @return list of ranges in encoded (raw) PSI
  */
 @Override
 @SuppressWarnings({"ConstantConditions", "unchecked"})
 @NotNull
 public List<TextRange> intersectWithAllEditableFragments(
     @NotNull PsiFile injectedPsi, @NotNull TextRange rangeToEdit) {
   Place shreds = InjectedLanguageUtil.getShreds(injectedPsi);
   if (shreds == null) return Collections.emptyList();
   Object result = null; // optimization: TextRange or ArrayList
   int count = 0;
   int offset = 0;
   for (PsiLanguageInjectionHost.Shred shred : shreds) {
     TextRange encodedRange =
         TextRange.from(
             offset + shred.getPrefix().length(), shred.getRangeInsideHost().getLength());
     TextRange intersection = encodedRange.intersection(rangeToEdit);
     if (intersection != null) {
       count++;
       if (count == 1) {
         result = intersection;
       } else if (count == 2) {
         TextRange range = (TextRange) result;
         if (range.isEmpty()) {
           result = intersection;
           count = 1;
         } else if (intersection.isEmpty()) {
           count = 1;
         } else {
           List<TextRange> list = new ArrayList<TextRange>();
           list.add(range);
           list.add(intersection);
           result = list;
         }
       } else if (intersection.isEmpty()) {
         count--;
       } else {
         ((List<TextRange>) result).add(intersection);
       }
     }
     offset +=
         shred.getPrefix().length()
             + shred.getRangeInsideHost().getLength()
             + shred.getSuffix().length();
   }
   return count == 0
       ? Collections.<TextRange>emptyList()
       : count == 1 ? Collections.singletonList((TextRange) result) : (List<TextRange>) result;
 }
  /**
   * After a wildcard (* or space), search for the first non-wildcard pattern character in the name
   * starting from nameIndex and try to {@link #matchFragment(String, int, int,
   * com.intellij.psi.codeStyle.MinusculeMatcher.MatchingState)} for it.
   */
  @Nullable
  private FList<TextRange> matchWildcards(
      @NotNull String name, int patternIndex, int nameIndex, MatchingState matchingState) {
    if (nameIndex < 0) {
      return null;
    }
    if (!isWildcard(patternIndex)) {
      if (patternIndex == myPattern.length) {
        return FList.emptyList();
      }
      return matchFragment(name, patternIndex, nameIndex, matchingState);
    }

    do {
      patternIndex++;
    } while (isWildcard(patternIndex));

    if (patternIndex == myPattern.length) {
      boolean space = isPatternChar(patternIndex - 1, ' ');
      // the trailing space should match if the pattern ends with the last word part, or only its
      // first hump character
      if (space
          && nameIndex != name.length()
          && (patternIndex < 2 || !NameUtil.isWordStart(myPattern[patternIndex - 2]))) {
        int spaceIndex = name.indexOf(' ', nameIndex);
        if (spaceIndex >= 0) {
          return FList.<TextRange>emptyList().prepend(TextRange.from(spaceIndex, 1));
        }
        return null;
      }
      return FList.emptyList();
    }

    FList<TextRange> ranges = matchFragment(name, patternIndex, nameIndex, matchingState);
    if (ranges != null) {
      return ranges;
    }

    return matchSkippingWords(name, patternIndex, nameIndex, true, matchingState);
  }
  @Override
  public void deleteString(final int startOffset, final int endOffset) {
    assert intersectWithEditable(new TextRange(startOffset, startOffset)) != null;
    assert intersectWithEditable(new TextRange(endOffset, endOffset)) != null;

    List<TextRange> hostRangesToDelete;
    synchronized (myLock) {
      hostRangesToDelete = new ArrayList<TextRange>(myShreds.size());

      int offset = startOffset;
      int curRangeStart = 0;
      for (PsiLanguageInjectionHost.Shred shred : myShreds) {
        curRangeStart += shred.getPrefix().length();
        if (offset < curRangeStart) offset = curRangeStart;
        if (offset >= endOffset) break;
        Segment hostRange = shred.getHostRangeMarker();
        if (hostRange == null) continue;
        int hostRangeLength = hostRange.getEndOffset() - hostRange.getStartOffset();
        TextRange range = TextRange.from(curRangeStart, hostRangeLength);
        if (range.contains(offset)) {
          TextRange rangeToDelete =
              new TextRange(offset, Math.min(range.getEndOffset(), endOffset));
          hostRangesToDelete.add(
              rangeToDelete.shiftRight(hostRange.getStartOffset() - curRangeStart));
          offset = rangeToDelete.getEndOffset();
        }
        curRangeStart += hostRangeLength;
        curRangeStart += shred.getSuffix().length();
      }
    }

    int delta = 0;
    for (TextRange hostRangeToDelete : hostRangesToDelete) {
      myDelegate.deleteString(
          hostRangeToDelete.getStartOffset() + delta, hostRangeToDelete.getEndOffset() + delta);
      delta -= hostRangeToDelete.getLength();
    }
  }
예제 #16
0
 public static TextRange getValueTextRange(final PsiElement element) {
   final ElementManipulator<PsiElement> manipulator = getManipulator(element);
   return manipulator == null
       ? TextRange.from(0, element.getTextLength())
       : manipulator.getRangeInElement(element);
 }
  private static TextRange preprocess(@NotNull final ASTNode node, @NotNull TextRange range) {
    TextRange result = range;
    PsiElement psi = node.getPsi();
    if (!psi.isValid()) {
      for (PreFormatProcessor processor : Extensions.getExtensions(PreFormatProcessor.EP_NAME)) {
        result = processor.process(node, result);
      }
      return result;
    }

    PsiFile file = psi.getContainingFile();

    // We use a set here because we encountered a situation when more than one PSI leaf points to
    // the same injected fragment
    // (at least for sql injected into sql).
    final LinkedHashSet<TextRange> injectedFileRangesSet = ContainerUtilRt.newLinkedHashSet();

    if (!psi.getProject().isDefault()) {
      List<DocumentWindow> injectedDocuments =
          InjectedLanguageUtil.getCachedInjectedDocuments(file);
      if (!injectedDocuments.isEmpty()) {
        for (DocumentWindow injectedDocument : injectedDocuments) {
          injectedFileRangesSet.add(
              TextRange.from(injectedDocument.injectedToHost(0), injectedDocument.getTextLength()));
        }
      } else {
        Collection<PsiLanguageInjectionHost> injectionHosts = collectInjectionHosts(file, range);
        PsiLanguageInjectionHost.InjectedPsiVisitor visitor =
            new PsiLanguageInjectionHost.InjectedPsiVisitor() {
              @Override
              public void visit(
                  @NotNull PsiFile injectedPsi,
                  @NotNull List<PsiLanguageInjectionHost.Shred> places) {
                for (PsiLanguageInjectionHost.Shred place : places) {
                  Segment rangeMarker = place.getHostRangeMarker();
                  injectedFileRangesSet.add(
                      TextRange.create(rangeMarker.getStartOffset(), rangeMarker.getEndOffset()));
                }
              }
            };
        for (PsiLanguageInjectionHost host : injectionHosts) {
          InjectedLanguageUtil.enumerate(host, visitor);
        }
      }
    }

    if (!injectedFileRangesSet.isEmpty()) {
      List<TextRange> ranges = ContainerUtilRt.newArrayList(injectedFileRangesSet);
      Collections.reverse(ranges);
      for (TextRange injectedFileRange : ranges) {
        int startHostOffset = injectedFileRange.getStartOffset();
        int endHostOffset = injectedFileRange.getEndOffset();
        if (startHostOffset >= range.getStartOffset() && endHostOffset <= range.getEndOffset()) {
          PsiFile injected = InjectedLanguageUtil.findInjectedPsiNoCommit(file, startHostOffset);
          if (injected != null) {
            int startInjectedOffset =
                range.getStartOffset() > startHostOffset
                    ? startHostOffset - range.getStartOffset()
                    : 0;
            int endInjectedOffset = injected.getTextLength();
            if (range.getEndOffset() < endHostOffset) {
              endInjectedOffset -= endHostOffset - range.getEndOffset();
            }
            final TextRange initialInjectedRange =
                TextRange.create(startInjectedOffset, endInjectedOffset);
            TextRange injectedRange = initialInjectedRange;
            for (PreFormatProcessor processor :
                Extensions.getExtensions(PreFormatProcessor.EP_NAME)) {
              injectedRange = processor.process(injected.getNode(), injectedRange);
            }

            // Allow only range expansion (not reduction) for injected context.
            if ((initialInjectedRange.getStartOffset() > injectedRange.getStartOffset()
                    && initialInjectedRange.getStartOffset() > 0)
                || (initialInjectedRange.getEndOffset() < injectedRange.getEndOffset()
                    && initialInjectedRange.getEndOffset() < injected.getTextLength())) {
              range =
                  TextRange.create(
                      range.getStartOffset()
                          + injectedRange.getStartOffset()
                          - initialInjectedRange.getStartOffset(),
                      range.getEndOffset()
                          + initialInjectedRange.getEndOffset()
                          - injectedRange.getEndOffset());
            }
          }
        }
      }
    }

    for (PreFormatProcessor processor : Extensions.getExtensions(PreFormatProcessor.EP_NAME)) {
      result = processor.process(node, result);
    }

    return result;
  }
 @Override
 public TextRange getRangeInElement() {
   return TextRange.from(0, stepPsiElement.getTextLength());
 }
  /**
   * Attempts to match an alphanumeric sequence of pattern (starting at patternIndex) to some
   * continuous substring of name, starting from nameIndex.
   */
  private FList<TextRange> doMatchFragments(
      String name, int patternIndex, int nameIndex, MatchingState matchingState) {
    if (!isFirstCharMatching(name, nameIndex, patternIndex)) {
      return null;
    }

    // middle matches have to be at least of length 3, to prevent too many irrelevant matches
    int minFragment =
        isPatternChar(patternIndex - 1, '*')
                && !isWildcard(patternIndex + 1)
                && Character.isLetterOrDigit(name.charAt(nameIndex))
                && !isWordStart(name, nameIndex)
            ? 3
            : 1;
    int i = 1;
    boolean ignoreCase = myOptions != NameUtil.MatchingCaseSensitivity.ALL;
    while (nameIndex + i < name.length()
        && patternIndex + i < myPattern.length
        && charEquals(
            myPattern[patternIndex + i],
            patternIndex + i,
            name.charAt(nameIndex + i),
            ignoreCase)) {
      if (isUpperCase[patternIndex + i] && myHasHumps) {
        if (i < minFragment) {
          return null;
        }
        // when an uppercase pattern letter matches lowercase name letter, try to find an uppercase
        // (better) match further in the name
        if (myPattern[patternIndex + i] != name.charAt(nameIndex + i)) {
          int nextWordStart = indexOfWordStart(name, patternIndex + i, nameIndex + i);
          FList<TextRange> ranges =
              matchWildcards(name, patternIndex + i, nextWordStart, matchingState);
          if (ranges != null) {
            return prependRange(ranges, nameIndex, i);
          }
          // at least three consecutive uppercase letters shouldn't match lowercase
          if (i > 1 && isUpperCase[patternIndex + i - 1] && isUpperCase[patternIndex + i - 2]) {
            // but if there's a lowercase after them, it can match (in case shift was released a bit
            // later)
            if (nameIndex + i + 1 == name.length()
                || patternIndex + i + 1 < myPattern.length && !isLowerCase[patternIndex + i + 1]) {
              return null;
            }
          }
        }
      }
      i++;
    }

    // we've found the longest fragment matching pattern and name

    if (patternIndex + i >= myPattern.length) {
      return FList.<TextRange>emptyList().prepend(TextRange.from(nameIndex, i));
    }

    // try to match the remainder of pattern with the remainder of name
    // it may not succeed with the longest matching fragment, then try shorter matches
    while (i >= minFragment || isWildcard(patternIndex + i)) {
      FList<TextRange> ranges =
          isWildcard(patternIndex + i)
              ? matchWildcards(name, patternIndex + i, nameIndex + i, matchingState)
              : matchSkippingWords(name, patternIndex + i, nameIndex + i, false, matchingState);
      if (ranges != null) {
        return prependRange(ranges, nameIndex, i);
      }
      i--;
    }
    return null;
  }
예제 #20
0
 public TextRange getRangeInElement() {
   return TextRange.from(1, myValue.getTextLength() - 2);
 }
예제 #21
0
 @NotNull
 public static PsiReference getReference(@NotNull DLanguageClassDeclaration o) {
   return new DReference(o, TextRange.from(0, getName(o).length()));
 }
예제 #22
0
  public void testMatchingFragments() {
    @NonNls String sample = "NoClassDefFoundException";
    //                       0 2    7  10   15    21
    assertOrderedEquals(
        new MinusculeMatcher("ncldfou*ion", NameUtil.MatchingCaseSensitivity.NONE)
            .matchingFragments(sample),
        TextRange.from(0, 1),
        TextRange.from(2, 2),
        TextRange.from(7, 1),
        TextRange.from(10, 3),
        TextRange.from(21, 3));

    sample = "doGet(HttpServletRequest, HttpServletResponse):void";
    //        0                     22
    assertOrderedEquals(
        new MinusculeMatcher("d*st", NameUtil.MatchingCaseSensitivity.NONE)
            .matchingFragments(sample),
        TextRange.from(0, 1),
        TextRange.from(22, 2));
    assertOrderedEquals(
        new MinusculeMatcher("doge*st", NameUtil.MatchingCaseSensitivity.NONE)
            .matchingFragments(sample),
        TextRange.from(0, 4),
        TextRange.from(22, 2));

    sample = "_test";
    assertOrderedEquals(
        new MinusculeMatcher("_", NameUtil.MatchingCaseSensitivity.NONE).matchingFragments(sample),
        TextRange.from(0, 1));
    assertOrderedEquals(
        new MinusculeMatcher("_t", NameUtil.MatchingCaseSensitivity.NONE).matchingFragments(sample),
        TextRange.from(0, 2));
  }
예제 #23
0
 @NotNull
 public static PsiReference getReference(@NotNull DLanguageIdentifier o) {
   return new DReference(o, TextRange.from(0, getName(o).length()));
 }