public TextRange getRangeInElement() { if (isSingleWord()) { return TextRange.from(0, getReferencedName().length()); } return TextRange.from(1, getReferencedName().length()); // fixme make sure it has the end } ? }
public TextRange getRangeInElement() { final PsiElement element = commandElement(); if (element == null) { return TextRange.from(0, getTextLength()); } return TextRange.from(element.getStartOffsetInParent(), element.getTextLength()); }
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)); }
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); }
private SchemaPrefixReference createPrefixReference( ASTNode startTagName, String prefix, TagNameReference tagRef) { return new SchemaPrefixReference( this, TextRange.from(startTagName.getStartOffset() - getStartOffset(), prefix.length()), prefix, tagRef); }
@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); }
@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(); } }
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; }
public TextRange getRangeInElement() { return TextRange.from(1, myValue.getTextLength() - 2); }
@NotNull public static PsiReference getReference(@NotNull DLanguageClassDeclaration o) { return new DReference(o, TextRange.from(0, getName(o).length())); }
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)); }
@NotNull public static PsiReference getReference(@NotNull DLanguageIdentifier o) { return new DReference(o, TextRange.from(0, getName(o).length())); }