@Override
 public void postProcess(PsiElement affectedElement, ReplaceOptions options) {
   if (!affectedElement.isValid()) {
     return;
   }
   if (options.isToUseStaticImport()) {
     shortenWithStaticImports(affectedElement, 0, affectedElement.getTextLength());
   }
   if (options.isToShortenFQN()) {
     final JavaCodeStyleManager codeStyleManager =
         JavaCodeStyleManager.getInstance(affectedElement.getProject());
     codeStyleManager.shortenClassReferences(affectedElement, 0, affectedElement.getTextLength());
   }
 }
 @Override
 public TextRange getRangeInElement() {
   final PsiElement token = getOpToken();
   assert token != null;
   final int offset = token.getStartOffsetInParent();
   return new TextRange(offset, offset + token.getTextLength());
 }
  @Override
  protected void collectAdditionalElementsToRename(List<Pair<PsiElement, TextRange>> stringUsages) {
    if (isReplaceAllOccurrences()) {
      for (E expression : getOccurrences()) {
        LOG.assertTrue(expression.isValid(), expression.getText());
        stringUsages.add(
            Pair.<PsiElement, TextRange>create(
                expression, new TextRange(0, expression.getTextLength())));
      }
    } else if (getExpr() != null) {
      correctExpression();
      final E expr = getExpr();
      LOG.assertTrue(expr.isValid(), expr.getText());
      stringUsages.add(
          Pair.<PsiElement, TextRange>create(expr, new TextRange(0, expr.getTextLength())));
    }

    final V localVariable = getLocalVariable();
    if (localVariable != null) {
      final PsiElement nameIdentifier = localVariable.getNameIdentifier();
      if (nameIdentifier != null) {
        int length = nameIdentifier.getTextLength();
        stringUsages.add(
            Pair.<PsiElement, TextRange>create(nameIdentifier, new TextRange(0, length)));
      }
    }
  }
Example #4
0
  public static PsiElement[] parsePattern(
      Project project,
      String context,
      String pattern,
      FileType fileType,
      Language language,
      String extension,
      boolean physical) {
    int offset = context.indexOf(PATTERN_PLACEHOLDER);

    final int patternLength = pattern.length();
    final String patternInContext = context.replace(PATTERN_PLACEHOLDER, pattern);

    final String ext = extension != null ? extension : fileType.getDefaultExtension();
    final String name = "__dummy." + ext;
    final PsiFileFactory factory = PsiFileFactory.getInstance(project);

    final PsiFile file =
        language == null
            ? factory.createFileFromText(
                name, fileType, patternInContext, LocalTimeCounter.currentTime(), physical, true)
            : factory.createFileFromText(name, language, patternInContext, physical, true);
    if (file == null) {
      return PsiElement.EMPTY_ARRAY;
    }

    final List<PsiElement> result = new ArrayList<PsiElement>();

    PsiElement element = file.findElementAt(offset);
    if (element == null) {
      return PsiElement.EMPTY_ARRAY;
    }

    PsiElement topElement = element;
    element = element.getParent();

    while (element != null) {
      if (element.getTextRange().getStartOffset() == offset
          && element.getTextLength() <= patternLength) {
        topElement = element;
      }
      element = element.getParent();
    }

    if (topElement instanceof PsiFile) {
      return topElement.getChildren();
    }

    final int endOffset = offset + patternLength;
    result.add(topElement);
    topElement = topElement.getNextSibling();

    while (topElement != null && topElement.getTextRange().getEndOffset() <= endOffset) {
      result.add(topElement);
      topElement = topElement.getNextSibling();
    }

    return result.toArray(new PsiElement[result.size()]);
  }
  public TextRange getRangeInElement() {
    final PsiElement element = commandElement();
    if (element == null) {
      return TextRange.from(0, getTextLength());
    }

    return TextRange.from(element.getStartOffsetInParent(), element.getTextLength());
  }
Example #6
0
 public Info(@NotNull PsiElement elementAtPointer) {
   this(
       elementAtPointer,
       Collections.singletonList(
           new TextRange(
               elementAtPointer.getTextOffset(),
               elementAtPointer.getTextOffset() + elementAtPointer.getTextLength())));
 }
  @Override
  protected void processIntention(@NotNull PsiElement element, Project project, Editor editor)
      throws IncorrectOperationException {
    final GrMethodCallExpression expression = (GrMethodCallExpression) element;
    final GrClosableBlock block = expression.getClosureArguments()[0];
    final GrParameterList parameterList = block.getParameterList();
    final GrParameter[] parameters = parameterList.getParameters();

    String var;
    if (parameters.length == 1) {
      var = parameters[0].getText();
      var = StringUtil.replace(var, GrModifier.DEF, "");
    } else {
      var = "it";
    }

    final GrExpression invokedExpression = expression.getInvokedExpression();
    GrExpression qualifier = ((GrReferenceExpression) invokedExpression).getQualifierExpression();
    final GroovyPsiElementFactory elementFactory =
        GroovyPsiElementFactory.getInstance(element.getProject());
    if (qualifier == null) {
      qualifier = elementFactory.createExpressionFromText("this");
    }

    StringBuilder builder = new StringBuilder();
    builder.append("for (").append(var).append(" in ").append(qualifier.getText()).append(") {\n");
    String text = block.getText();
    final PsiElement blockArrow = block.getArrow();
    int index;
    if (blockArrow != null) {
      index = blockArrow.getStartOffsetInParent() + blockArrow.getTextLength();
    } else {
      index = 1;
    }
    while (index < text.length() && Character.isWhitespace(text.charAt(index))) index++;
    text = text.substring(index, text.length() - 1);
    builder.append(text);
    builder.append("}");

    final GrStatement statement = elementFactory.createStatementFromText(builder.toString());
    GrForStatement forStatement = (GrForStatement) expression.replaceWithStatement(statement);
    final GrForClause clause = forStatement.getClause();
    GrVariable variable = clause.getDeclaredVariable();

    forStatement = updateReturnStatements(forStatement);

    if (variable == null) return;

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

    final PsiDocumentManager documentManager = PsiDocumentManager.getInstance(project);
    final Document doc = documentManager.getDocument(element.getContainingFile());
    if (doc == null) return;

    documentManager.doPostponedOperationsAndUnblockDocument(doc);
    editor.getCaretModel().moveToOffset(variable.getTextOffset());
    new VariableInplaceRenamer(variable, editor).performInplaceRename();
  }
Example #8
0
    @Override
    public void visitElement(PsiElement element) {
      super.visitElement(element);

      final EquivalenceDescriptorProvider descriptorProvider =
          EquivalenceDescriptorProvider.getInstance(element);

      if (descriptorProvider != null) {
        final EquivalenceDescriptor descriptor1 = descriptorProvider.buildDescriptor(element);
        final EquivalenceDescriptor descriptor2 =
            descriptorProvider.buildDescriptor(myGlobalVisitor.getElement());

        if (descriptor1 != null && descriptor2 != null) {
          final boolean result =
              DuplocatorUtil.match(
                  descriptor1,
                  descriptor2,
                  myGlobalVisitor,
                  Collections.<PsiElementRole>emptySet(),
                  null);
          myGlobalVisitor.setResult(result);
          return;
        }
      }

      if (isLiteral(element)) {
        visitLiteral(element);
        return;
      }

      if (canBePatternVariable(element)
          && myGlobalVisitor.getMatchContext().getPattern().isRealTypedVar(element)
          && !shouldIgnoreVarNode(element)) {

        PsiElement matchedElement = myGlobalVisitor.getElement();
        PsiElement newElement = SkippingHandler.skipNodeIfNeccessary(matchedElement);
        while (newElement != matchedElement) {
          matchedElement = newElement;
          newElement = SkippingHandler.skipNodeIfNeccessary(matchedElement);
        }

        myGlobalVisitor.setResult(myGlobalVisitor.handleTypedElement(element, matchedElement));
      } else if (element instanceof LeafElement) {
        myGlobalVisitor.setResult(element.getText().equals(myGlobalVisitor.getElement().getText()));
      } else if (element.getFirstChild() == null && element.getTextLength() == 0) {
        myGlobalVisitor.setResult(true);
      } else {
        PsiElement patternChild = element.getFirstChild();
        PsiElement matchedChild = myGlobalVisitor.getElement().getFirstChild();

        FilteringNodeIterator patternIterator = new SsrFilteringNodeIterator(patternChild);
        FilteringNodeIterator matchedIterator = new SsrFilteringNodeIterator(matchedChild);

        boolean matched = myGlobalVisitor.matchSequentially(patternIterator, matchedIterator);
        myGlobalVisitor.setResult(matched);
      }
    }
 /**
  * There is a following possible use-case:
  *
  * <pre>
  * <ul>
  *   <li>
  *     <b>Particular document has valid text:</b>
  *     <pre>
  *       [caret]
  *       class A {
  *           int foo() {
  *             return 1 *&#47;*comment*&#47; 1;
  *           }
  *       }
  *     </pre>
  *   </li>
  *   <li>
  *     <b>The user starts comment (inserts comment start symbols):</b>
  *     <pre>
  *       &#47;**[caret]
  *       class A {
  *           int foo() {
  *             return 1 *&#47;*comment*&#47; 1;
  *           }
  *       }
  *     </pre>
  *   </li>
  *   <li>The user presses <code>'enter'</code>;</li>
  * </ul>
  * </pre>
  *
  * We want to understand that doc comment is incomplete now, i.e. don't want to consider '*&#47;'
  * before '*comment*&#47; 1;' as comment end. Current approach is to check if next PSI sibling to
  * the current PSI comment is invalid. This method allows to perform such an examination.
  */
 private static boolean isInvalidPsi(@NotNull PsiElement base) {
   for (PsiElement current = base.getNextSibling();
       current != null;
       current = current.getNextSibling()) {
     if (current.getTextLength() != 0) {
       return current instanceof PsiErrorElement;
     }
   }
   return false;
 }
 protected final void registerError(@NotNull PsiElement location, Object... infos) {
   if (location.getTextLength() == 0) {
     return;
   }
   final InspectionGadgetsFix[] fixes = createFixes(infos);
   for (InspectionGadgetsFix fix : fixes) {
     fix.setOnTheFly(onTheFly);
   }
   final String description = inspection.buildErrorString(infos);
   holder.registerProblem(location, description, fixes);
 }
  @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 void appendAdditionalElement(
     Collection<Pair<PsiElement, TextRange>> stringUsages,
     PsiNamedElement variable,
     PsiElement element) {
   if (element != variable
       && element instanceof PsiNameIdentifierOwner
       && !notSameFile(null, element.getContainingFile())) {
     final PsiElement identifier = ((PsiNameIdentifierOwner) element).getNameIdentifier();
     if (identifier != null) {
       stringUsages.add(Pair.create(identifier, new TextRange(0, identifier.getTextLength())));
     }
   }
 }
  protected void updateTitle(@Nullable V variable, String value) {
    if (variable == null) return;

    final String variableText = variable.getText();
    final PsiElement identifier = variable.getNameIdentifier();
    if (identifier != null) {
      final int startOffsetInParent = identifier.getStartOffsetInParent();
      setPreviewText(
          variableText.substring(0, startOffsetInParent)
              + value
              + variableText.substring(startOffsetInParent + identifier.getTextLength()));
    } else {
      setPreviewText(variableText.replaceFirst(variable.getName(), value));
    }
    revalidate();
  }
  protected int getCloseQuoteOffset() {
    PsiElement lastChild = getLastChild();

    if (lastChild instanceof PerlParsableStringWrapperlImpl) {
      PsiElement realString = lastChild.getFirstChild();
      assert realString instanceof PerlStringImplMixin;
      return ((PerlStringImplMixin) realString).getCloseQuoteOffset();
    }

    ASTNode currentNode = lastChild.getNode();

    if (PerlParserUtil.CLOSE_QUOTES.contains(currentNode.getElementType()))
      return currentNode.getStartOffset();

    // unclosed string
    return lastChild.getTextOffset() + lastChild.getTextLength();
  }
 public static void sendBeforeChildrenChangeEvent(
     @NotNull PsiManagerImpl manager, @NotNull PsiElement scope, boolean isGenericChange) {
   if (!scope.isPhysical()) {
     manager.beforeChange(false);
     return;
   }
   PsiTreeChangeEventImpl event = new PsiTreeChangeEventImpl(manager);
   event.setParent(scope);
   event.setFile(scope.getContainingFile());
   TextRange range = scope.getTextRange();
   event.setOffset(range == null ? 0 : range.getStartOffset());
   event.setOldLength(scope.getTextLength());
   // the "generic" event is being sent on every PSI change. It does not carry any specific info
   // except the fact that "something has changed"
   event.setGenericChange(isGenericChange);
   manager.beforeChildrenChange(event);
 }
 @Override
 public String getUnescapedText(@NotNull final PsiElement injectedNode) {
   final StringBuilder text = new StringBuilder(injectedNode.getTextLength());
   // gather text from (patched) leaves
   injectedNode.accept(
       new PsiRecursiveElementWalkingVisitor() {
         @Override
         public void visitElement(PsiElement element) {
           String leafText = InjectedLanguageUtil.getUnescapedLeafText(element, false);
           if (leafText != null) {
             text.append(leafText);
             return;
           }
           super.visitElement(element);
         }
       });
   return text.toString();
 }
  @NotNull
  public PsiReference[] getReferencesByElement(
      @NotNull PsiElement element, @NotNull final ProcessingContext context) {
    boolean soft = myDefaultSoft;

    if (element instanceof XmlAttributeValue) {
      final XmlAttribute xmlAttribute = (XmlAttribute) element.getParent();
      if (element.getTextLength() < 2) {
        return PsiReference.EMPTY_ARRAY;
      }

      final XmlTag tag = xmlAttribute.getParent();
      String value = null;
      String bundle = tag.getAttributeValue("bundle");
      if ("key".equals(xmlAttribute.getName())) {
        value = xmlAttribute.getValue();
      } else if ("groupKey".equals(xmlAttribute.getName())) {
        value = xmlAttribute.getValue();
        final String groupBundle = tag.getAttributeValue("groupBundle");
        if (groupBundle != null) {
          bundle = groupBundle;
        }
      }
      if (value != null) {
        return new PsiReference[] {
          new PropertyReference(value, xmlAttribute.getValueElement(), bundle, soft) {
            @Override
            protected List<PropertiesFile> retrievePropertyFilesByBundleName(
                String bundleName, PsiElement element) {
              final Project project = element.getProject();
              return PropertiesReferenceManager.getInstance(project)
                  .findPropertiesFiles(
                      GlobalSearchScope.projectScope(project),
                      bundleName,
                      BundleNameEvaluator.DEFAULT);
            }
          }
        };
      }
    }
    return PsiReference.EMPTY_ARRAY;
  }
 @Override
 public String getUnescapedText(@NotNull final PsiElement injectedNode) {
   final StringBuilder text = new StringBuilder(injectedNode.getTextLength());
   // gather text from (patched) leaves
   injectedNode.accept(
       new PsiRecursiveElementWalkingVisitor() {
         @Override
         public void visitElement(PsiElement element) {
           String unescaped = element.getCopyableUserData(UNESCAPED_TEXT);
           if (unescaped != null) {
             text.append(unescaped);
             return;
           }
           if (element.getFirstChild() == null) {
             text.append(element.getText());
             return;
           }
           super.visitElement(element);
         }
       });
   return text.toString();
 }
  @NotNull
  public GrStatement addStatementBefore(@NotNull GrStatement element, @Nullable GrStatement anchor)
      throws IncorrectOperationException {
    if (anchor == null && getRBrace() == null) {
      throw new IncorrectOperationException();
    }

    if (anchor != null && !this.equals(anchor.getParent())) {
      throw new IncorrectOperationException();
    }

    final LeafElement nls =
        Factory.createSingleLeafElement(GroovyTokenTypes.mNLS, "\n", 0, 1, null, getManager());

    PsiElement actualAnchor = anchor == null ? getRBrace() : anchor;
    if (mayUseNewLinesAsSeparators()) {
      PsiElement prev = actualAnchor.getPrevSibling();
      if (prev instanceof GrParameterList
          && prev.getTextLength() == 0
          && prev.getPrevSibling() != null) {
        prev = prev.getPrevSibling();
      }
      if (!PsiUtil.isLineFeed(prev)) {
        addBefore(nls.getPsi(), actualAnchor);
      }
    }
    element = (GrStatement) addBefore(element, actualAnchor);
    if (mayUseNewLinesAsSeparators()) {
      addBefore(nls.getPsi(), actualAnchor);
    } else {
      addBefore(
          Factory.createSingleLeafElement(GroovyTokenTypes.mNLS, "\n", 0, 1, null, getManager())
              .getPsi(),
          actualAnchor);
    }
    return element;
  }
Example #20
0
    public void visitLiteral(PsiElement literal) {
      final PsiElement l2 = myGlobalVisitor.getElement();

      MatchingHandler handler = (MatchingHandler) literal.getUserData(CompiledPattern.HANDLER_KEY);

      if (handler instanceof SubstitutionHandler) {
        int offset = 0;
        int length = l2.getTextLength();
        final String text = l2.getText();

        if (length > 2 && (text.charAt(0) == '"' && text.charAt(length - 1) == '"')
            || (text.charAt(0) == '\'' && text.charAt(length - 1) == '\'')) {
          length--;
          offset++;
        }
        myGlobalVisitor.setResult(
            ((SubstitutionHandler) handler)
                .handle(l2, offset, length, myGlobalVisitor.getMatchContext()));
      } else if (handler != null) {
        myGlobalVisitor.setResult(handler.match(literal, l2, myGlobalVisitor.getMatchContext()));
      } else {
        myGlobalVisitor.setResult(literal.textMatches(l2));
      }
    }
  @Override
  protected void checkTag(
      @NotNull final XmlTag tag, @NotNull final ProblemsHolder holder, final boolean isOnTheFly) {
    if (!(tag instanceof HtmlTag)
        || !XmlHighlightVisitor.shouldBeValidated(tag)
        || isInSpecialHtml5Namespace(tag)) {
      return;
    }

    XmlElementDescriptor descriptorFromContext = XmlUtil.getDescriptorFromContext(tag);

    PsiElement parent = tag.getParent();
    XmlElementDescriptor parentDescriptor =
        parent instanceof XmlTag ? ((XmlTag) parent).getDescriptor() : null;

    XmlElementDescriptor ownDescriptor =
        isAbstractDescriptor(descriptorFromContext) ? tag.getDescriptor() : descriptorFromContext;

    if (isAbstractDescriptor(ownDescriptor)
        || (parentDescriptor instanceof HtmlElementDescriptorImpl
            && ownDescriptor instanceof HtmlElementDescriptorImpl
            && isAbstractDescriptor(descriptorFromContext))) {

      final String name = tag.getName();

      if (!isCustomValuesEnabled() || !isCustomValue(name)) {
        final AddCustomTagOrAttributeIntentionAction action =
            new AddCustomTagOrAttributeIntentionAction(
                TAG_KEY, name, XmlEntitiesInspection.UNKNOWN_TAG);

        // todo: support "element is not allowed" message for html5
        // some tags in html5 cannot be found in xhtml5.xsd if they are located in incorrect
        // context, so they get any-element descriptor (ex. "canvas: tag)
        final String message =
            isAbstractDescriptor(ownDescriptor)
                ? XmlErrorMessages.message("unknown.html.tag", name)
                : XmlErrorMessages.message("element.is.not.allowed.here", name);

        final PsiElement startTagName = XmlTagUtil.getStartTagNameElement(tag);
        assert startTagName != null;
        final PsiElement endTagName = XmlTagUtil.getEndTagNameElement(tag);

        List<LocalQuickFix> quickfixes = new ArrayList<LocalQuickFix>();
        quickfixes.add(action);
        if (isOnTheFly) {
          ContainerUtil.addIfNotNull(
              CreateNSDeclarationIntentionFix.createFix(startTagName, ""), quickfixes);
        }
        if (HtmlUtil.isHtml5Tag(name) && !HtmlUtil.hasNonHtml5Doctype(tag)) {
          quickfixes.add(new SwitchToHtml5WithHighPriorityAction());
        }
        ProblemHighlightType highlightType =
            tag.getContainingFile().getContext() == null
                ? ProblemHighlightType.GENERIC_ERROR_OR_WARNING
                : ProblemHighlightType.INFORMATION;
        if (startTagName.getTextLength() > 0) {
          holder.registerProblem(
              startTagName,
              message,
              highlightType,
              quickfixes.toArray(new LocalQuickFix[quickfixes.size()]));
        }

        if (endTagName != null) {
          holder.registerProblem(
              endTagName,
              message,
              highlightType,
              quickfixes.toArray(new LocalQuickFix[quickfixes.size()]));
        }
      }
    }
  }
Example #22
0
  private static void divideInsideAndOutside(
      @NotNull PsiFile root,
      int startOffset,
      int endOffset,
      @NotNull TextRange range,
      @NotNull List<PsiElement> inside,
      @NotNull List<PsiElement> outside,
      boolean includeParents) {
    final int currentOffset = root.getTextRange().getStartOffset();
    final Condition<PsiElement>[] filters = Extensions.getExtensions(CollectHighlightsUtil.EP_NAME);

    int offset = currentOffset;

    final TIntStack starts = new TIntStack(STARTING_TREE_HEIGHT);
    starts.push(startOffset);
    final Stack<PsiElement> elements = new Stack<PsiElement>(STARTING_TREE_HEIGHT);
    final Stack<PsiElement> children = new Stack<PsiElement>(STARTING_TREE_HEIGHT);
    PsiElement element = root;

    PsiElement child = PsiUtilBase.NULL_PSI_ELEMENT;
    while (true) {
      ProgressManager.checkCanceled();

      for (Condition<PsiElement> filter : filters) {
        if (!filter.value(element)) {
          assert child == PsiUtilBase.NULL_PSI_ELEMENT;
          child = null; // do not want to process children
          break;
        }
      }

      boolean startChildrenVisiting;
      if (child == PsiUtilBase.NULL_PSI_ELEMENT) {
        startChildrenVisiting = true;
        child = element.getFirstChild();
      } else {
        startChildrenVisiting = false;
      }

      if (child == null) {
        if (startChildrenVisiting) {
          // leaf element
          offset += element.getTextLength();
        }

        int start = starts.pop();
        if (startOffset <= start && offset <= endOffset) {
          if (range.containsRange(start, offset)) {
            inside.add(element);
          } else {
            outside.add(element);
          }
        }

        if (elements.isEmpty()) break;
        element = elements.pop();
        child = children.pop();
      } else {
        // composite element
        if (offset > endOffset) break;
        children.push(child.getNextSibling());
        starts.push(offset);
        elements.push(element);
        element = child;
        child = PsiUtilBase.NULL_PSI_ELEMENT;
      }
    }

    if (includeParents) {
      PsiElement parent =
          !outside.isEmpty()
              ? outside.get(outside.size() - 1)
              : !inside.isEmpty()
                  ? inside.get(inside.size() - 1)
                  : CollectHighlightsUtil.findCommonParent(root, startOffset, endOffset);
      while (parent != null && parent != root) {
        parent = parent.getParent();
        if (parent != null) outside.add(parent);
      }
    }
  }
Example #23
0
 public boolean textMatches(@NotNull PsiElement element) {
   return getTextLength() == element.getTextLength() && textMatches(element.getText());
 }
Example #24
0
  public static boolean areParenthesesNecessary(
      @NotNull JetExpression innerExpression,
      @NotNull JetExpression currentInner,
      @NotNull JetExpression parentExpression) {
    if (parentExpression instanceof JetParenthesizedExpression
        || innerExpression instanceof JetParenthesizedExpression) {
      return false;
    }

    if (parentExpression instanceof JetWhenExpression
        || innerExpression instanceof JetWhenExpression) {
      return false;
    }

    if (innerExpression instanceof JetIfExpression) {
      PsiElement current = parentExpression;

      while (!(current instanceof JetBlockExpression
          || current instanceof JetDeclaration
          || current instanceof JetStatementExpression)) {
        if (current.getTextRange().getEndOffset() != currentInner.getTextRange().getEndOffset()) {
          return current.getText().charAt(current.getTextLength() - 1)
              != ')'; // if current expression is "guarded" by parenthesis, no extra parenthesis is
                      // necessary
        }

        current = current.getParent();
      }
    }

    IElementType innerOperation = getOperation(innerExpression);
    IElementType parentOperation = getOperation(parentExpression);

    // 'return (@label{...})' case
    if (parentExpression instanceof JetReturnExpression
        && innerOperation == JetTokens.LABEL_IDENTIFIER) {
      return true;
    }

    // '(x: Int) < y' case
    if (innerExpression instanceof JetBinaryExpressionWithTypeRHS
        && parentOperation == JetTokens.LT) {
      return true;
    }

    int innerPriority = getPriority(innerExpression);
    int parentPriority = getPriority(parentExpression);

    if (innerPriority == parentPriority) {
      if (parentExpression instanceof JetBinaryExpression) {
        if (innerOperation == JetTokens.ANDAND || innerOperation == JetTokens.OROR) {
          return false;
        }
        return ((JetBinaryExpression) parentExpression).getRight() == currentInner;
      }

      // '-(-x)' case
      if (parentExpression instanceof JetPrefixExpression
          && innerExpression instanceof JetPrefixExpression) {
        return innerOperation == parentOperation
            && (innerOperation == JetTokens.PLUS || innerOperation == JetTokens.MINUS);
      }
      return false;
    }

    return innerPriority < parentPriority;
  }
 @Override
 public TextRange getRangeInElement() {
   final PsiElement opToken = getOperationToken();
   final int offset = opToken.getStartOffsetInParent();
   return new TextRange(offset, offset + opToken.getTextLength());
 }