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());
    }
  }
예제 #2
0
 @Nullable
 public static String getReferencePrefix(@NotNull PsiElement insertedElement, int offsetInFile) {
   final PsiReference ref = insertedElement.getContainingFile().findReferenceAt(offsetInFile);
   if (ref != null) {
     final PsiElement element = ref.getElement();
     final int endIndex = offsetInFile - element.getTextRange().getStartOffset();
     final int beginIndex = ref.getRangeInElement().getStartOffset();
     if (beginIndex > endIndex) {
       LOG.error(
           "Inconsistent reference (found at offset not included in its range): ref="
               + ref
               + " element="
               + element
               + " text="
               + element.getText());
     }
     if (beginIndex < 0) {
       LOG.error(
           "Inconsistent reference (begin < 0): ref="
               + ref
               + " element="
               + element
               + "; begin="
               + beginIndex
               + " text="
               + element.getText());
     }
     LOG.assertTrue(endIndex >= 0);
     return element.getText().substring(beginIndex, endIndex);
   }
   return null;
 }
예제 #3
0
  @NotNull
  public static String getElementTextWithContext(@NotNull JetElement element) {
    if (element instanceof JetFile) {
      return element.getContainingFile().getText();
    }

    // Find parent for element among file children
    PsiElement inFileParent =
        PsiTreeUtil.findFirstParent(
            element,
            new Condition<PsiElement>() {
              @Override
              public boolean value(PsiElement parentCandidate) {
                return parentCandidate != null && parentCandidate.getParent() instanceof JetFile;
              }
            });

    assert inFileParent != null
        : "For non-file element we should always be able to find parent in file children";

    int startContextOffset = inFileParent.getTextRange().getStartOffset();
    int elementContextOffset = element.getTextRange().getStartOffset();

    int inFileParentOffset = elementContextOffset - startContextOffset;

    return new StringBuilder(inFileParent.getText())
        .insert(inFileParentOffset, "<caret>")
        .toString();
  }
예제 #4
0
  public static Editor positionCursor(
      final Project project, PsiFile targetFile, PsiElement element) {
    TextRange range = element.getTextRange();
    int textOffset = range.getStartOffset();

    OpenFileDescriptor descriptor =
        new OpenFileDescriptor(project, targetFile.getVirtualFile(), textOffset);
    return FileEditorManager.getInstance(project).openTextEditor(descriptor, true);
  }
  private static void findClassUsages(
      final PsiClass psiClass,
      final PsiElement[] allElementsToDelete,
      final List<UsageInfo> usages) {
    final boolean justPrivates = containsOnlyPrivates(psiClass);
    final String qualifiedName = psiClass.getQualifiedName();
    final boolean annotationType = psiClass.isAnnotationType() && qualifiedName != null;

    ReferencesSearch.search(psiClass)
        .forEach(
            reference -> {
              final PsiElement element = reference.getElement();

              if (!isInside(element, allElementsToDelete)) {
                PsiElement parent = element.getParent();
                if (parent instanceof PsiReferenceList) {
                  final PsiElement pparent = parent.getParent();
                  if (pparent instanceof PsiClass
                      && element instanceof PsiJavaCodeReferenceElement) {
                    final PsiClass inheritor = (PsiClass) pparent;
                    // If psiClass contains only private members, then it is safe to remove it and
                    // change inheritor's extends/implements accordingly
                    if (justPrivates) {
                      if (parent.equals(inheritor.getExtendsList())
                          || parent.equals(inheritor.getImplementsList())) {
                        usages.add(
                            new SafeDeleteExtendsClassUsageInfo(
                                (PsiJavaCodeReferenceElement) element, psiClass, inheritor));
                        return true;
                      }
                    }
                  }
                }
                LOG.assertTrue(element.getTextRange() != null);
                final PsiFile containingFile = psiClass.getContainingFile();
                boolean sameFileWithSingleClass = false;
                if (containingFile instanceof PsiClassOwner) {
                  final PsiClass[] classes = ((PsiClassOwner) containingFile).getClasses();
                  sameFileWithSingleClass =
                      classes.length == 1
                          && classes[0] == psiClass
                          && element.getContainingFile() == containingFile;
                }

                final boolean safeDelete = sameFileWithSingleClass || isInNonStaticImport(element);
                if (annotationType && parent instanceof PsiAnnotation) {
                  usages.add(
                      new SafeDeleteAnnotation((PsiAnnotation) parent, psiClass, safeDelete));
                } else {
                  usages.add(
                      new SafeDeleteReferenceJavaDeleteUsageInfo(element, psiClass, safeDelete));
                }
              }
              return true;
            });
  }
  private void getInjectedPsiFiles(
      @NotNull final List<PsiElement> elements1,
      @NotNull final List<PsiElement> elements2,
      @NotNull final ProgressIndicator progress,
      @NotNull final Set<PsiFile> outInjected) {
    List<DocumentWindow> injected = InjectedLanguageUtil.getCachedInjectedDocuments(myFile);
    Collection<PsiElement> hosts =
        new THashSet<PsiElement>(elements1.size() + elements2.size() + injected.size());

    // rehighlight all injected PSI regardless the range,
    // since change in one place can lead to invalidation of injected PSI in (completely) other
    // place.
    for (DocumentWindow documentRange : injected) {
      progress.checkCanceled();
      if (!documentRange.isValid()) continue;
      PsiFile file = PsiDocumentManager.getInstance(myProject).getPsiFile(documentRange);
      if (file == null) continue;
      PsiElement context =
          InjectedLanguageManager.getInstance(file.getProject()).getInjectionHost(file);
      if (context != null
          && context.isValid()
          && !file.getProject().isDisposed()
          && (myUpdateAll
              || new ProperTextRange(myStartOffset, myEndOffset)
                  .intersects(context.getTextRange()))) {
        hosts.add(context);
      }
    }
    hosts.addAll(elements1);
    hosts.addAll(elements2);

    final PsiLanguageInjectionHost.InjectedPsiVisitor visitor =
        new PsiLanguageInjectionHost.InjectedPsiVisitor() {
          @Override
          public void visit(
              @NotNull PsiFile injectedPsi, @NotNull List<PsiLanguageInjectionHost.Shred> places) {
            synchronized (outInjected) {
              outInjected.add(injectedPsi);
            }
          }
        };
    if (!JobUtil.invokeConcurrentlyUnderProgress(
        new ArrayList<PsiElement>(hosts),
        progress,
        false,
        new Processor<PsiElement>() {
          @Override
          public boolean process(PsiElement element) {
            progress.checkCanceled();
            InjectedLanguageUtil.enumerate(element, myFile, false, visitor);
            return true;
          }
        })) throw new ProcessCanceledException();
  }
  private static Collection<String> suggestKeywords(PsiElement position) {
    TextRange posRange = position.getTextRange();
    BnfFile posFile = (BnfFile) position.getContainingFile();
    BnfRule statement = PsiTreeUtil.getTopmostParentOfType(position, BnfRule.class);
    final TextRange range;
    if (statement != null) {
      range = new TextRange(statement.getTextRange().getStartOffset(), posRange.getStartOffset());
    } else {
      int offset = posRange.getStartOffset();
      for (PsiElement cur = GrammarUtil.getDummyAwarePrevSibling(position);
          cur != null;
          cur = GrammarUtil.getDummyAwarePrevSibling(cur)) {
        if (cur instanceof BnfAttrs) offset = cur.getTextRange().getEndOffset();
        else if (cur instanceof BnfRule) offset = cur.getTextRange().getStartOffset();
        else continue;
        break;
      }
      range = new TextRange(offset, posRange.getStartOffset());
    }
    final String text =
        range.isEmpty()
            ? CompletionInitializationContext.DUMMY_IDENTIFIER
            : range.substring(posFile.getText());

    PsiFile file =
        PsiFileFactory.getInstance(posFile.getProject())
            .createFileFromText("a.bnf", BnfLanguage.INSTANCE, text, true, false);
    int completionOffset = posRange.getStartOffset() - range.getStartOffset();
    GeneratedParserUtilBase.CompletionState state =
        new GeneratedParserUtilBase.CompletionState(completionOffset) {
          @Override
          public String convertItem(Object o) {
            // we do not have other keywords
            return o instanceof String ? (String) o : null;
          }
        };
    file.putUserData(GeneratedParserUtilBase.COMPLETION_STATE_KEY, state);
    TreeUtil.ensureParsed(file.getNode());
    return state.items;
  }
예제 #8
0
 @Nullable
 public static TextRange getSelectedRange(Editor editor, final PsiFile psiFile) {
   if (editor == null) return null;
   String selectedText = editor.getSelectionModel().getSelectedText();
   if (selectedText != null) {
     return new TextRange(
         editor.getSelectionModel().getSelectionStart(),
         editor.getSelectionModel().getSelectionEnd());
   }
   PsiElement psiElement = psiFile.findElementAt(editor.getCaretModel().getOffset());
   if (psiElement == null || psiElement instanceof PsiWhiteSpace) return null;
   return psiElement.getTextRange();
 }
  private static boolean shouldSkipLine(final PsiFile file, Document doc, int line) {
    final int start = doc.getLineStartOffset(line);
    final int end = doc.getLineEndOffset(line);
    final int _start = CharArrayUtil.shiftForward(doc.getCharsSequence(), start, " \n\t");
    if (_start >= end) {
      return true;
    }

    TextRange alreadyChecked = null;
    for (PsiElement elem = file.findElementAt(_start);
        elem != null
            && elem.getTextOffset() <= end
            && (alreadyChecked == null || !alreadyChecked.contains(elem.getTextRange()));
        elem = elem.getNextSibling()) {
      for (PsiElement _elem = elem; _elem.getTextOffset() >= _start; _elem = _elem.getParent()) {
        alreadyChecked = _elem.getTextRange();

        if (_elem instanceof PsiDeclarationStatement) {
          final PsiElement[] declared = ((PsiDeclarationStatement) _elem).getDeclaredElements();
          for (PsiElement declaredElement : declared) {
            if (declaredElement instanceof PsiVariable) {
              return false;
            }
          }
        }

        if (_elem instanceof PsiJavaCodeReferenceElement) {
          final PsiElement resolved = ((PsiJavaCodeReferenceElement) _elem).resolve();
          if (resolved instanceof PsiVariable) {
            return false;
          }
        }
      }
    }
    return true;
  }
예제 #10
0
 @Nullable
 public static PsiExpression findExpressionInRange(PsiFile file, int startOffset, int endOffset) {
   if (!file.getViewProvider().getLanguages().contains(StdLanguages.JAVA)) return null;
   PsiExpression expression =
       findElementInRange(file, startOffset, endOffset, PsiExpression.class);
   if (expression == null && findStatementsInRange(file, startOffset, endOffset).length == 0) {
     PsiElement element2 = file.getViewProvider().findElementAt(endOffset - 1, StdLanguages.JAVA);
     if (element2 instanceof PsiJavaToken) {
       final PsiJavaToken token = (PsiJavaToken) element2;
       final IElementType tokenType = token.getTokenType();
       if (tokenType.equals(JavaTokenType.SEMICOLON)) {
         expression =
             findElementInRange(
                 file, startOffset, element2.getTextRange().getStartOffset(), PsiExpression.class);
       }
     }
   }
   if (expression == null && findStatementsInRange(file, startOffset, endOffset).length == 0) {
     PsiElement element =
         PsiTreeUtil.skipSiblingsBackward(file.findElementAt(endOffset), PsiWhiteSpace.class);
     if (element != null) {
       element =
           PsiTreeUtil.skipSiblingsBackward(
               element.getLastChild(), PsiWhiteSpace.class, PsiComment.class);
       if (element != null) {
         final int newEndOffset = element.getTextRange().getEndOffset();
         if (newEndOffset < endOffset) {
           expression = findExpressionInRange(file, startOffset, newEndOffset);
         }
       }
     }
   }
   if (expression instanceof PsiReferenceExpression
       && expression.getParent() instanceof PsiMethodCallExpression) return null;
   return expression;
 }
예제 #11
0
  protected static String findPrefixDefault(
      final PsiElement insertedElement, final int offset, @NotNull final ElementPattern trimStart) {
    String substr =
        insertedElement
            .getText()
            .substring(0, offset - insertedElement.getTextRange().getStartOffset());
    if (substr.length() == 0 || Character.isWhitespace(substr.charAt(substr.length() - 1)))
      return "";

    substr = substr.trim();

    int i = 0;
    while (substr.length() > i && trimStart.accepts(substr.charAt(i))) i++;
    return substr.substring(i).trim();
  }
예제 #12
0
 public static boolean intersects(@NotNull TextRange range, @NotNull PsiElement elem) {
   TextRange elemRange = elem.getTextRange();
   return elemRange != null && elemRange.intersects(range);
 }
    public void replace(
        int psiStart, int length, @NotNull String replace, @Nullable PsiElement replacement) {
      // calculating fragment
      // minimize replace
      int start = 0;
      int end = start + length;

      final CharSequence chars = myPsiText.subSequence(psiStart, psiStart + length);
      if (StringUtil.equals(chars, replace)) return;

      int newStartInReplace = 0;
      final int replaceLength = replace.length();
      while (newStartInReplace < replaceLength
          && start < end
          && replace.charAt(newStartInReplace) == chars.charAt(start)) {
        start++;
        newStartInReplace++;
      }

      int newEndInReplace = replaceLength;
      while (start < end
          && newStartInReplace < newEndInReplace
          && replace.charAt(newEndInReplace - 1) == chars.charAt(end - 1)) {
        newEndInReplace--;
        end--;
      }

      // increase the changed range to start and end on PSI token boundaries
      // this will help to survive smart pointers with the same boundaries
      if (replacement != null && (newStartInReplace > 0 || newEndInReplace < replaceLength)) {
        PsiElement startLeaf = replacement.findElementAt(newStartInReplace);
        PsiElement endLeaf = replacement.findElementAt(newEndInReplace - 1);
        if (startLeaf != null && endLeaf != null) {
          int leafStart =
              startLeaf.getTextRange().getStartOffset()
                  - replacement.getTextRange().getStartOffset();
          int leafEnd =
              endLeaf.getTextRange().getEndOffset() - replacement.getTextRange().getStartOffset();
          start += leafStart - newStartInReplace;
          end += leafEnd - newEndInReplace;
          newStartInReplace = leafStart;
          newEndInReplace = leafEnd;
        }
      }

      // optimization: when delete fragment from the middle of the text, prefer split at the line
      // boundaries
      if (newStartInReplace == newEndInReplace
          && start > 0
          && start < end
          && StringUtil.indexOf(chars, '\n', start, end) != -1) {
        // try to align to the line boundaries
        while (start > 0
            && newStartInReplace > 0
            && chars.charAt(start - 1) == chars.charAt(end - 1)
            && chars.charAt(end - 1) != '\n') {
          start--;
          end--;
          newStartInReplace--;
          newEndInReplace--;
        }
      }

      start += psiStart;
      end += psiStart;

      // [mike] dirty hack for xml:
      // make sure that deletion of <t> in: <tag><t/><tag> doesn't remove t/><
      // which is perfectly valid but invalidates range markers
      final CharSequence charsSequence = myPsiText;
      while (start < charsSequence.length()
          && end < charsSequence.length()
          && start > 0
          && charsSequence.subSequence(start, end).toString().endsWith("><")
          && charsSequence.charAt(start - 1) == '<') {
        start--;
        newStartInReplace--;
        end--;
        newEndInReplace--;
      }

      updateFragments(start, end, replace.substring(newStartInReplace, newEndInReplace));
    }
  public static int insertClassReference(
      PsiClass psiClass, PsiFile file, int startOffset, int endOffset) {
    final Project project = file.getProject();
    PsiDocumentManager documentManager = PsiDocumentManager.getInstance(project);
    documentManager.commitAllDocuments();

    final PsiManager manager = file.getManager();

    final Document document =
        FileDocumentManager.getInstance().getDocument(file.getViewProvider().getVirtualFile());

    final PsiReference reference = file.findReferenceAt(startOffset);
    if (reference != null) {
      final PsiElement resolved = reference.resolve();
      if (resolved instanceof PsiClass) {
        if (((PsiClass) resolved).getQualifiedName() == null
            || manager.areElementsEquivalent(psiClass, resolved)) {
          return endOffset;
        }
      }
    }

    String name = psiClass.getName();
    if (name == null) {
      return endOffset;
    }

    assert document != null;
    document.replaceString(startOffset, endOffset, name);

    int newEndOffset = startOffset + name.length();
    final RangeMarker toDelete = insertTemporary(newEndOffset, document, " ");

    documentManager.commitAllDocuments();

    PsiElement element = file.findElementAt(startOffset);
    if (element instanceof PsiIdentifier) {
      PsiElement parent = element.getParent();
      if (parent instanceof PsiJavaCodeReferenceElement
          && !((PsiJavaCodeReferenceElement) parent).isQualified()
          && !(parent.getParent() instanceof PsiPackageStatement)) {
        PsiJavaCodeReferenceElement ref = (PsiJavaCodeReferenceElement) parent;

        if (psiClass.isValid()
            && !psiClass.getManager().areElementsEquivalent(psiClass, resolveReference(ref))) {
          final boolean staticImport = ref instanceof PsiImportStaticReferenceElement;
          PsiElement newElement;
          try {
            newElement =
                staticImport
                    ? ((PsiImportStaticReferenceElement) ref).bindToTargetClass(psiClass)
                    : ref.bindToElement(psiClass);
          } catch (IncorrectOperationException e) {
            return endOffset; // can happen if fqn contains reserved words, for example
          }

          final RangeMarker rangeMarker = document.createRangeMarker(newElement.getTextRange());
          documentManager.doPostponedOperationsAndUnblockDocument(document);
          documentManager.commitDocument(document);

          newElement =
              CodeInsightUtilCore.findElementInRange(
                  file,
                  rangeMarker.getStartOffset(),
                  rangeMarker.getEndOffset(),
                  PsiJavaCodeReferenceElement.class,
                  JavaLanguage.INSTANCE);
          rangeMarker.dispose();
          if (newElement != null) {
            newEndOffset = newElement.getTextRange().getEndOffset();
            if (!(newElement instanceof PsiReferenceExpression)) {
              PsiReferenceParameterList parameterList =
                  ((PsiJavaCodeReferenceElement) newElement).getParameterList();
              if (parameterList != null) {
                newEndOffset = parameterList.getTextRange().getStartOffset();
              }
            }

            if (!staticImport
                && !psiClass
                    .getManager()
                    .areElementsEquivalent(psiClass, resolveReference((PsiReference) newElement))
                && !PsiUtil.isInnerClass(psiClass)) {
              final String qName = psiClass.getQualifiedName();
              if (qName != null) {
                document.replaceString(
                    newElement.getTextRange().getStartOffset(), newEndOffset, qName);
                newEndOffset = newElement.getTextRange().getStartOffset() + qName.length();
              }
            }
          }
        }
      }
    }

    if (toDelete.isValid()) {
      document.deleteString(toDelete.getStartOffset(), toDelete.getEndOffset());
    }

    return newEndOffset;
  }
예제 #15
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;
  }
예제 #16
0
  @NotNull
  public static PsiElement[] findStatementsInRange(
      @NotNull PsiFile file, int startOffset, int endOffset) {
    Language language = findJavaOrLikeLanguage(file);
    if (language == null) return PsiElement.EMPTY_ARRAY;
    FileViewProvider viewProvider = file.getViewProvider();
    PsiElement element1 = viewProvider.findElementAt(startOffset, language);
    PsiElement element2 = viewProvider.findElementAt(endOffset - 1, language);
    if (element1 instanceof PsiWhiteSpace) {
      startOffset = element1.getTextRange().getEndOffset();
      element1 = file.findElementAt(startOffset);
    }
    if (element2 instanceof PsiWhiteSpace) {
      endOffset = element2.getTextRange().getStartOffset();
      element2 = file.findElementAt(endOffset - 1);
    }
    if (element1 == null || element2 == null) return PsiElement.EMPTY_ARRAY;

    PsiElement parent = PsiTreeUtil.findCommonParent(element1, element2);
    if (parent == null) return PsiElement.EMPTY_ARRAY;
    while (true) {
      if (parent instanceof PsiStatement) {
        parent = parent.getParent();
        break;
      }
      if (parent instanceof PsiCodeBlock) break;
      // if (JspPsiUtil.isInJspFile(parent) && parent instanceof PsiFile) break;
      if (parent instanceof PsiCodeFragment) break;
      if (parent == null || parent instanceof PsiFile) return PsiElement.EMPTY_ARRAY;
      parent = parent.getParent();
    }

    if (!parent.equals(element1)) {
      while (!parent.equals(element1.getParent())) {
        element1 = element1.getParent();
      }
    }
    if (startOffset != element1.getTextRange().getStartOffset()) return PsiElement.EMPTY_ARRAY;

    if (!parent.equals(element2)) {
      while (!parent.equals(element2.getParent())) {
        element2 = element2.getParent();
      }
    }
    if (endOffset != element2.getTextRange().getEndOffset()) return PsiElement.EMPTY_ARRAY;

    if (parent instanceof PsiCodeBlock
        && parent.getParent() instanceof PsiBlockStatement
        && element1 == ((PsiCodeBlock) parent).getLBrace()
        && element2 == ((PsiCodeBlock) parent).getRBrace()) {
      return new PsiElement[] {parent.getParent()};
    }

    /*
        if(parent instanceof PsiCodeBlock && parent.getParent() instanceof PsiBlockStatement) {
          return new PsiElement[]{parent.getParent()};
        }
    */

    PsiElement[] children = parent.getChildren();
    ArrayList<PsiElement> array = new ArrayList<PsiElement>();
    boolean flag = false;
    for (PsiElement child : children) {
      if (child.equals(element1)) {
        flag = true;
      }
      if (flag && !(child instanceof PsiWhiteSpace)) {
        array.add(child);
      }
      if (child.equals(element2)) {
        break;
      }
    }

    for (PsiElement element : array) {
      if (!(element instanceof PsiStatement
          || element instanceof PsiWhiteSpace
          || element instanceof PsiComment)) {
        return PsiElement.EMPTY_ARRAY;
      }
    }

    return PsiUtilCore.toPsiElementArray(array);
  }
  @NotNull
  private Set<PsiFile> getInjectedPsiFiles(
      @NotNull final List<PsiElement> elements1,
      @NotNull final List<PsiElement> elements2,
      @NotNull final ProgressIndicator progress) {
    ApplicationManager.getApplication().assertReadAccessAllowed();
    final Set<PsiFile> outInjected = new THashSet<PsiFile>();

    List<DocumentWindow> injected = InjectedLanguageUtil.getCachedInjectedDocuments(myFile);
    final Collection<PsiElement> hosts =
        new THashSet<PsiElement>(elements1.size() + elements2.size() + injected.size());

    // rehighlight all injected PSI regardless the range,
    // since change in one place can lead to invalidation of injected PSI in (completely) other
    // place.
    for (DocumentWindow documentRange : injected) {
      progress.checkCanceled();
      if (!documentRange.isValid()) continue;
      PsiFile file = PsiDocumentManager.getInstance(myProject).getPsiFile(documentRange);
      if (file == null) continue;
      PsiElement context =
          InjectedLanguageManager.getInstance(file.getProject()).getInjectionHost(file);
      if (context != null
          && context.isValid()
          && !file.getProject().isDisposed()
          && (myUpdateAll || myRestrictRange.intersects(context.getTextRange()))) {
        hosts.add(context);
      }
    }
    InjectedLanguageManagerImpl injectedLanguageManager =
        InjectedLanguageManagerImpl.getInstanceImpl(myProject);
    Processor<PsiElement> collectInjectableProcessor =
        new CommonProcessors.CollectProcessor<PsiElement>(hosts);
    injectedLanguageManager.processInjectableElements(elements1, collectInjectableProcessor);
    injectedLanguageManager.processInjectableElements(elements2, collectInjectableProcessor);

    final PsiLanguageInjectionHost.InjectedPsiVisitor visitor =
        new PsiLanguageInjectionHost.InjectedPsiVisitor() {
          @Override
          public void visit(
              @NotNull PsiFile injectedPsi, @NotNull List<PsiLanguageInjectionHost.Shred> places) {
            synchronized (outInjected) {
              outInjected.add(injectedPsi);
            }
          }
        };
    if (!JobLauncher.getInstance()
        .invokeConcurrentlyUnderProgress(
            new ArrayList<PsiElement>(hosts),
            progress,
            true,
            new Processor<PsiElement>() {
              @Override
              public boolean process(PsiElement element) {
                ApplicationManager.getApplication().assertReadAccessAllowed();
                progress.checkCanceled();
                InjectedLanguageUtil.enumerate(element, myFile, false, visitor);
                return true;
              }
            })) {
      throw new ProcessCanceledException();
    }
    synchronized (outInjected) {
      return outInjected;
    }
  }
 @Override
 public void visitElement(final PsiElement element) {
   if (myLineRange.intersects(element.getTextRange())) {
     super.visitElement(element);
   }
 }