예제 #1
0
  // Returns null if standalone closing brace is not found
  private static BraceStatus checkForMovableClosingBrace(
      @NotNull Editor editor, @NotNull PsiFile file, @NotNull MoveInfo info, boolean down) {
    PsiElement closingBrace = getStandaloneClosingBrace(file, editor);
    if (closingBrace == null) return BraceStatus.NOT_FOUND;

    PsiElement blockLikeElement = closingBrace.getParent();
    if (!(blockLikeElement instanceof JetBlockExpression)) return BraceStatus.NOT_MOVABLE;

    PsiElement blockParent = blockLikeElement.getParent();
    if (blockParent instanceof JetWhenEntry) return BraceStatus.NOT_FOUND;
    if (PsiTreeUtil.instanceOf(blockParent, FUNCTIONLIKE_ELEMENT_CLASSES))
      return BraceStatus.NOT_FOUND;

    PsiElement enclosingExpression =
        PsiTreeUtil.getParentOfType(blockLikeElement, JetExpression.class);

    if (enclosingExpression instanceof JetDoWhileExpression) return BraceStatus.NOT_MOVABLE;

    if (enclosingExpression instanceof JetIfExpression) {
      JetIfExpression ifExpression = (JetIfExpression) enclosingExpression;

      if (blockLikeElement == ifExpression.getThen() && ifExpression.getElse() != null)
        return BraceStatus.NOT_MOVABLE;
    }

    return down
        ? checkForMovableDownClosingBrace(closingBrace, blockLikeElement, editor, info)
        : checkForMovableUpClosingBrace(closingBrace, blockLikeElement, editor, info);
  }
  private void updateEditorText() {
    disposeNonTextEditor();

    final PsiElement elt = myElements[myIndex].getNavigationElement();
    Project project = elt.getProject();
    PsiFile psiFile = getContainingFile(elt);
    final VirtualFile vFile = psiFile.getVirtualFile();
    if (vFile == null) return;
    final FileEditorProvider[] providers =
        FileEditorProviderManager.getInstance().getProviders(project, vFile);
    for (FileEditorProvider provider : providers) {
      if (provider instanceof TextEditorProvider) {
        updateTextElement(elt);
        myBinarySwitch.show(myViewingPanel, TEXT_PAGE_KEY);
        break;
      } else if (provider.accept(project, vFile)) {
        myCurrentNonTextEditorProvider = provider;
        myNonTextEditor = myCurrentNonTextEditorProvider.createEditor(project, vFile);
        myBinaryPanel.removeAll();
        myBinaryPanel.add(myNonTextEditor.getComponent());
        myBinarySwitch.show(myViewingPanel, BINARY_PAGE_KEY);
        break;
      }
    }
  }
  @Nullable
  @Override
  public String getType(PsiElement e) {
    if (DumbService.getInstance(e.getProject()).isDumb()
        || !Settings.getInstance(e.getProject()).pluginEnabled
        || !Settings.getInstance(e.getProject()).objectManagerFindTypeProvider) {
      return null;
    }

    if (!(e instanceof MethodReference)
        || !PhpElementsUtil.isMethodWithFirstStringOrFieldReference(e, "find")) {
      return null;
    }

    String refSignature = ((MethodReference) e).getSignature();
    if (StringUtil.isEmpty(refSignature)) {
      return null;
    }

    // we need the param key on getBySignature(), since we are already in the resolved method there
    // attach it to signature
    // param can have dotted values split with \
    PsiElement[] parameters = ((MethodReference) e).getParameters();
    if (parameters.length == 2) {
      return PhpTypeProviderUtil.getReferenceSignature((MethodReference) e, TRIM_KEY, 2);
    }

    return null;
  }
  private PsiElement getStatementToInsertBefore() {
    PsiElement declarationScope =
        myVariable instanceof PsiParameter
            ? ((PsiParameter) myVariable).getDeclarationScope()
            : PsiUtil.getVariableCodeBlock(myVariable, null);
    if (declarationScope == null) return null;

    PsiElement statement = myClass;
    nextInnerClass:
    do {
      statement = PsiUtil.getEnclosingStatement(statement);

      if (statement == null || statement.getParent() == null) {
        return null;
      }
      PsiElement element = statement;
      while (element != declarationScope && !(element instanceof PsiFile)) {
        if (element instanceof PsiClass) {
          statement = statement.getParent();
          continue nextInnerClass;
        }
        element = element.getParent();
      }
      return statement;
    } while (true);
  }
 private static void addUnfinishedMethodTypeParameters(
     PsiElement position, final Consumer<LookupElement> result) {
   final ProcessingContext context = new ProcessingContext();
   if (psiElement()
       .inside(
           psiElement(PsiTypeElement.class)
               .afterLeaf(
                   psiElement()
                       .withText(">")
                       .withParent(
                           psiElement(PsiTypeParameterList.class)
                               .withParent(PsiErrorElement.class)
                               .save("typeParameterList"))))
       .accepts(position, context)) {
     final PsiTypeParameterList list = (PsiTypeParameterList) context.get("typeParameterList");
     PsiElement current = list.getParent().getParent();
     if (current instanceof PsiField) {
       current = current.getParent();
     }
     if (current instanceof PsiClass) {
       for (PsiTypeParameter typeParameter : list.getTypeParameters()) {
         result.consume(new JavaPsiClassReferenceElement(typeParameter));
       }
     }
   }
 }
 public static boolean validElement(@NotNull PsiElement element) {
   if (element instanceof PsiFile) return true;
   if (!element.isPhysical()) return false;
   final RefactoringSupportProvider provider =
       LanguageRefactoringSupport.INSTANCE.forLanguage(element.getLanguage());
   return provider.isSafeDeleteAvailable(element);
 }
예제 #7
0
  @Override
  public PsiElement getTopLevelElement(PsiElement element) {
    PsiFile file = element.getContainingFile();
    if (file == null || !(file instanceof JetFile)) return null;

    VirtualFile virtualFile = file.getVirtualFile();
    if (!fileInRoots(virtualFile)) return file;

    PsiElement current = element;
    while (current != null) {
      if (isSelectable(current)) break;
      current = current.getParent();
    }

    if (current instanceof JetFile) {
      List<JetDeclaration> declarations = ((JetFile) current).getDeclarations();
      String nameWithoutExtension =
          virtualFile != null ? virtualFile.getNameWithoutExtension() : file.getName();
      if (declarations.size() == 1
          && declarations.get(0) instanceof JetClassOrObject
          && nameWithoutExtension.equals(declarations.get(0).getName())) {
        current = declarations.get(0);
      }
    }

    return current != null ? current : file;
  }
 @Override
 public boolean shouldCreateStub(ASTNode node) {
   PsiElement element = node.getPsi();
   return element instanceof PerlMooseAugmentStatement
       && element.isValid()
       && StringUtil.isNotEmpty(((PerlMooseAugmentStatement) element).getSubName());
 }
예제 #9
0
  @NotNull
  private static String getMultilineDocCommentText(final @NotNull DartDocComment docComment) {
    final StringBuilder buf = new StringBuilder();
    boolean afterAsterisk = false;

    for (PsiElement child = docComment.getFirstChild();
        child != null;
        child = child.getNextSibling()) {
      final IElementType elementType = child.getNode().getElementType();
      final String text = child.getText();

      if (elementType != DartTokenTypesSets.MULTI_LINE_DOC_COMMENT_START
          && elementType != DartTokenTypesSets.DOC_COMMENT_LEADING_ASTERISK
          && elementType != DartTokenTypesSets.MULTI_LINE_COMMENT_END) {
        int newLinesCount;
        if (child instanceof PsiWhiteSpace
            && (newLinesCount = StringUtil.countNewLines(text)) > 0) {
          buf.append(StringUtil.repeatSymbol('\n', newLinesCount));
        } else {
          if (afterAsterisk && text.startsWith(" ")) {
            buf.append(text.substring(1));
          } else {
            buf.append(text);
          }
        }
      }

      afterAsterisk = elementType == DartTokenTypesSets.DOC_COMMENT_LEADING_ASTERISK;
    }

    return buf.toString();
  }
    @Override
    public boolean satisfiedBy(@NotNull PsiElement element) {
      if (!(element instanceof JSStatement)) {
        return false;
      }
      if (element instanceof JSBlockStatement) {
        return false;
      }

      final PsiElement parentElement = element.getParent();
      if (!(parentElement instanceof JSElement)) return false;
      final JSElement parent = (JSElement) parentElement;

      if (parent instanceof JSIfStatement) {
        final JSIfStatement ifStatement = (JSIfStatement) parent;

        return (!(element instanceof JSIfStatement && element.equals(ifStatement.getElse())));
      }

      if (parent instanceof JSForStatement || parent instanceof JSForInStatement) {
        return element.equals(((JSLoopStatement) parent).getBody());
      }

      return (parent instanceof JSWhileStatement || parent instanceof JSDoWhileStatement);
    }
예제 #11
0
  private static void assertResolvedCallsAreCompleted(
      @NotNull Diagnostic diagnostic,
      @NotNull Collection<? extends ResolvedCall<?>> resolvedCalls) {
    boolean allCallsAreCompleted = true;
    for (ResolvedCall<?> resolvedCall : resolvedCalls) {
      if (!((MutableResolvedCall<?>) resolvedCall).isCompleted()) {
        allCallsAreCompleted = false;
      }
    }

    PsiElement element = diagnostic.getPsiElement();
    DiagnosticUtils.LineAndColumn lineAndColumn =
        DiagnosticUtils.getLineAndColumnInPsiFile(
            element.getContainingFile(), element.getTextRange());

    assertTrue(
        "Resolved calls stored in "
            + diagnostic.getFactory().getName()
            + "\n"
            + "for '"
            + element.getText()
            + "'"
            + lineAndColumn
            + " are not completed",
        allCallsAreCompleted);
  }
  @Override
  public void visitClassInitializer(PsiClassInitializer initializer) {
    JavaElementArrangementEntry entry =
        createNewEntry(initializer, initializer.getTextRange(), FIELD, null, true);
    if (entry == null) {
      return;
    }

    PsiElement classLBrace = null;
    PsiClass clazz = initializer.getContainingClass();
    if (clazz != null) {
      classLBrace = clazz.getLBrace();
    }
    for (PsiElement e = initializer.getPrevSibling(); e != null; e = e.getPrevSibling()) {
      JavaElementArrangementEntry prevEntry;
      if (e == classLBrace) {
        prevEntry = myEntries.get(clazz);
      } else {
        prevEntry = myEntries.get(e);
      }
      if (prevEntry != null) {
        entry.addDependency(prevEntry);
      }
      if (!(e instanceof PsiWhiteSpace)) {
        break;
      }
    }
  }
  @Override
  public void visitField(PsiField field) {
    // There is a possible case that more than one field is declared for the same type like 'int i,
    // j;'. We want to process only
    // the first one then.
    PsiElement fieldPrev = getPreviousNonWsComment(field.getPrevSibling(), 0);
    if (fieldPrev instanceof PsiJavaToken
        && ((PsiJavaToken) fieldPrev).getTokenType() == JavaTokenType.COMMA) {
      return;
    }

    // There is a possible case that fields which share the same type declaration are located on
    // different document lines, e.g.:
    //    int i1,
    //        i2;
    // We want to consider only the first declaration then but need to expand its range to all
    // affected lines (up to semicolon).
    TextRange range = field.getTextRange();
    PsiElement child = field.getLastChild();
    boolean needSpecialProcessing = true;
    if (isSemicolon(child)) {
      needSpecialProcessing = false;
    } else if (child instanceof PsiComment) {
      // There is a possible field definition like below:
      //   int f; // my comment.
      // The comment goes into field PSI here, that's why we need to handle it properly.
      PsiElement prev = getPreviousNonWsComment(child, range.getStartOffset());
      needSpecialProcessing = prev != null && !isSemicolon(prev);
    }

    if (needSpecialProcessing) {
      for (PsiElement e = field.getNextSibling(); e != null; e = e.getNextSibling()) {
        if (e instanceof PsiWhiteSpace || e instanceof PsiComment) { // Skip white space and comment
          continue;
        } else if (e instanceof PsiJavaToken) {
          if (((PsiJavaToken) e).getTokenType() == JavaTokenType.COMMA) { // Skip comma
            continue;
          } else {
            break;
          }
        } else if (e instanceof PsiField) {
          PsiElement c = e.getLastChild();
          if (c != null) {
            c = getPreviousNonWsComment(c, range.getStartOffset());
          }
          // Stop if current field ends by a semicolon.
          if (c instanceof PsiErrorElement // Incomplete field without trailing semicolon
              || (c instanceof PsiJavaToken
                  && ((PsiJavaToken) c).getTokenType() == JavaTokenType.SEMICOLON)) {
            range = TextRange.create(range.getStartOffset(), c.getTextRange().getEndOffset());
          } else {
            continue;
          }
        }
        break;
      }
    }
    JavaElementArrangementEntry entry = createNewEntry(field, range, FIELD, field.getName(), true);
    processEntry(entry, field, field.getInitializer());
  }
예제 #14
0
  @Nullable
  private static JetBlockExpression findClosestBlock(
      @NotNull PsiElement anchor, boolean down, boolean strict) {
    PsiElement current = PsiTreeUtil.getParentOfType(anchor, JetBlockExpression.class, strict);
    while (current != null) {
      PsiElement parent = current.getParent();
      if (parent instanceof JetClassBody
          || parent instanceof JetClassInitializer
          || parent instanceof JetNamedFunction
          || (parent instanceof JetProperty && !((JetProperty) parent).isLocal())) {
        return null;
      }

      if (parent instanceof JetBlockExpression) return (JetBlockExpression) parent;

      PsiElement sibling = down ? current.getNextSibling() : current.getPrevSibling();
      if (sibling != null) {
        //noinspection unchecked
        JetBlockExpression block =
            (JetBlockExpression)
                JetPsiUtil.getOutermostDescendantElement(sibling, down, CHECK_BLOCK);
        if (block != null) return block;

        current = sibling;
      } else {
        current = parent;
      }
    }

    return null;
  }
 public TextRange getTextRangeForNavigation() {
   TextRange textRange = getTextRange();
   if (textRange == null) return null;
   PsiElement element = getPsiElement();
   return InjectedLanguageManager.getInstance(element.getProject())
       .injectedToHost(element, textRange);
 }
  @Override
  public boolean doEnter(Editor editor, PsiElement psiElement, boolean isModified) {
    PsiCodeBlock block = getControlStatementBlock(editor.getCaretModel().getOffset(), psiElement);
    if (processExistingBlankLine(editor, block, psiElement)) {
      return true;
    }
    EditorActionHandler enterHandler = getEnterHandler(IdeActions.ACTION_EDITOR_START_NEW_LINE);
    if (block != null) {
      PsiElement firstElement = block.getFirstBodyElement();
      if (firstElement == null) {
        firstElement = block.getRBrace();
        // Plain enter processor inserts enter after the end of line, hence, we don't want to use it
        // here because the line ends with
        // the empty braces block. So, we get the following in case of default handler usage:
        //     Before:
        //         if (condition[caret]) {}
        //     After:
        //         if (condition) {}
        //             [caret]
        enterHandler = getEnterHandler(IdeActions.ACTION_EDITOR_ENTER);
      }
      editor
          .getCaretModel()
          .moveToOffset(
              firstElement != null
                  ? firstElement.getTextRange().getStartOffset()
                  : block.getTextRange().getEndOffset());
    }

    enterHandler.execute(editor, ((EditorEx) editor).getDataContext());
    return true;
  }
  @Override
  protected void performRefactoring(@NotNull UsageInfo[] usages) {
    try {
      for (UsageInfo usage : usages) {
        if (usage instanceof SafeDeleteCustomUsageInfo) {
          ((SafeDeleteCustomUsageInfo) usage).performRefactoring();
        }
      }

      DumbService.allowStartingDumbModeInside(
          DumbModePermission.MAY_START_MODAL,
          () -> {
            for (PsiElement element : myElements) {
              for (SafeDeleteProcessorDelegate delegate :
                  Extensions.getExtensions(SafeDeleteProcessorDelegate.EP_NAME)) {
                if (delegate.handlesElement(element)) {
                  delegate.prepareForDeletion(element);
                }
              }

              element.delete();
            }
          });
    } catch (IncorrectOperationException e) {
      RefactoringUIUtil.processIncorrectOperation(myProject, e);
    }
  }
 @Nullable
 private static PsiClass getFieldOrMethodAccessedClass(
     PsiReferenceExpression ref, PsiClass fieldOrMethodClass) {
   PsiElement[] children = ref.getChildren();
   if (children.length > 1 && children[0] instanceof PsiExpression) {
     PsiExpression expr = (PsiExpression) children[0];
     PsiType type = expr.getType();
     if (type != null) {
       if (!(type instanceof PsiClassType)) return null;
       return PsiUtil.resolveClassInType(type);
     } else {
       if (expr instanceof PsiReferenceExpression) {
         PsiElement refElement = ((PsiReferenceExpression) expr).resolve();
         if (refElement instanceof PsiClass) return (PsiClass) refElement;
       }
       return null;
     }
   }
   PsiManager manager = ref.getManager();
   for (PsiElement parent = ref; parent != null; parent = parent.getParent()) {
     if (parent instanceof PsiClass
         && (manager.areElementsEquivalent(parent, fieldOrMethodClass)
             || ((PsiClass) parent).isInheritor(fieldOrMethodClass, true))) {
       return (PsiClass) parent;
     }
   }
   return null;
 }
예제 #19
0
 private static List<? extends PsiElement> resolveSimpleReference(
     @NotNull DartReference reference) {
   final List<? extends PsiElement> result =
       resolveSimpleReference(reference, reference.getCanonicalText());
   final PsiElement parent = reference.getParent();
   final PsiElement superParent = parent.getParent();
   final boolean isSimpleConstructor =
       parent instanceof DartType
           && superParent instanceof DartNewExpression
           && ((DartNewExpression) superParent).getReferenceExpression() == null;
   if (!isSimpleConstructor || result.isEmpty()) {
     return result;
   }
   final List<PsiElement> filteredResult = new ArrayList<PsiElement>(result.size());
   for (PsiElement element : result) {
     final PsiElement elementParent = element.getParent();
     if (element instanceof DartComponentName && elementParent instanceof DartClass) {
       final DartComponent component =
           ((DartClass) elementParent).findNamedConstructor(reference.getCanonicalText());
       if (component != null
           && DartComponentType.typeOf(component) == DartComponentType.CONSTRUCTOR) {
         filteredResult.add(component.getComponentName());
         continue;
       }
     }
     filteredResult.add(element);
   }
   return filteredResult;
 }
    public PsiElement[] getElements() {
      if (myElements == null) return PsiElement.EMPTY_ARRAY;

      int validElementsCount = 0;

      for (PsiElement element : myElements) {
        if (element.isValid()) {
          validElementsCount++;
        }
      }

      if (validElementsCount == myElements.length) {
        return myElements;
      }

      PsiElement[] validElements = new PsiElement[validElementsCount];
      int j = 0;
      for (PsiElement element : myElements) {
        if (element.isValid()) {
          validElements[j++] = element;
        }
      }

      myElements = validElements;
      return myElements;
    }
  /**
   * Creates PathReference from resolve result.
   *
   * @param path Path to resolve.
   * @param element Context element.
   * @param staticIcon Static icon or {@code null} for resolve target's icon.
   * @return PathReference or {@code null} if no references.
   */
  @Nullable
  protected PathReference createDefaultPathReference(
      final String path, final PsiElement element, @Nullable final Icon staticIcon) {
    final ArrayList<PsiReference> list = new ArrayList<PsiReference>(5);
    createReferences(element, list, true);
    if (list.isEmpty()) {
      return null;
    }

    final PsiElement target = list.get(list.size() - 1).resolve();
    if (target == null) {
      return null;
    }

    final Function<PathReference, Icon> iconFunction;
    if (staticIcon == null) {
      iconFunction = webPath -> target.getIcon(Iconable.ICON_FLAG_READ_STATUS);
    } else {
      iconFunction = new ConstantFunction<PathReference, Icon>(staticIcon);
    }

    return new PathReference(path, iconFunction) {
      public PsiElement resolve() {
        return target;
      }
    };
  }
예제 #22
0
 private static boolean statementCanBePlacedAlong(final PsiElement element) {
   if (element instanceof JspTemplateStatement) {
     PsiElement neighbour = element.getPrevSibling();
     // we can place statement inside scriptlet only
     return neighbour != null && !(neighbour instanceof JspTemplateStatement);
   }
   if (element instanceof PsiBlockStatement) return false;
   final PsiElement parent = element.getParent();
   if (parent instanceof JspClassLevelDeclarationStatement) return false;
   if (parent instanceof PsiCodeBlock) return true;
   if (parent instanceof PsiIfStatement
       && (element == ((PsiIfStatement) parent).getThenBranch()
           || element == ((PsiIfStatement) parent).getElseBranch())) {
     return true;
   }
   if (parent instanceof PsiWhileStatement && element == ((PsiWhileStatement) parent).getBody()) {
     return true;
   }
   if (parent instanceof PsiDoWhileStatement
       && element == ((PsiDoWhileStatement) parent).getBody()) {
     return true;
   }
   // know nothing about that
   return false;
 }
  private static TailType getReturnTail(PsiElement position) {
    PsiElement scope = position;
    while (true) {
      if (scope instanceof PsiFile || scope instanceof PsiClassInitializer) {
        return TailType.NONE;
      }

      if (scope instanceof PsiMethod) {
        final PsiMethod method = (PsiMethod) scope;
        if (method.isConstructor() || PsiType.VOID.equals(method.getReturnType())) {
          return TailType.SEMICOLON;
        }

        return TailType.HUMBLE_SPACE_BEFORE_WORD;
      }
      if (scope instanceof PsiLambdaExpression) {
        final PsiType returnType =
            LambdaUtil.getFunctionalInterfaceReturnType(((PsiLambdaExpression) scope));
        if (PsiType.VOID.equals(returnType)) {
          return TailType.SEMICOLON;
        }
        return TailType.HUMBLE_SPACE_BEFORE_WORD;
      }
      scope = scope.getParent();
    }
  }
예제 #24
0
 public static MultiMap<PsiElement, UsageInfo> classifyUsages(
     Collection<? extends PsiElement> elements, UsageInfo[] usages) {
   final MultiMap<PsiElement, UsageInfo> result = new MultiMap<PsiElement, UsageInfo>();
   for (UsageInfo usage : usages) {
     LOG.assertTrue(usage instanceof MoveRenameUsageInfo);
     if (usage.getReference() instanceof LightElement) {
       continue; // filter out implicit references (e.g. from derived class to super class' default
                 // constructor)
     }
     MoveRenameUsageInfo usageInfo = (MoveRenameUsageInfo) usage;
     if (usage instanceof RelatedUsageInfo) {
       final PsiElement relatedElement = ((RelatedUsageInfo) usage).getRelatedElement();
       if (elements.contains(relatedElement)) {
         result.putValue(relatedElement, usage);
       }
     } else {
       PsiElement referenced = usageInfo.getReferencedElement();
       if (elements.contains(referenced)) {
         result.putValue(referenced, usage);
       } else if (referenced != null) {
         PsiElement indirect = referenced.getNavigationElement();
         if (elements.contains(indirect)) {
           result.putValue(indirect, usage);
         }
       }
     }
   }
   return result;
 }
  private static boolean isStatementPosition(PsiElement position) {
    if (PsiTreeUtil.getNonStrictParentOfType(position, PsiLiteralExpression.class, PsiComment.class)
        != null) {
      return false;
    }

    if (psiElement()
        .withSuperParent(2, PsiConditionalExpression.class)
        .andNot(psiElement().insideStarting(psiElement(PsiConditionalExpression.class)))
        .accepts(position)) {
      return false;
    }

    if (END_OF_BLOCK.getValue().isAcceptable(position, position)
        && PsiTreeUtil.getParentOfType(position, PsiCodeBlock.class, true, PsiMember.class)
            != null) {
      return true;
    }

    if (psiElement()
        .withParents(
            PsiReferenceExpression.class, PsiExpressionStatement.class, PsiIfStatement.class)
        .andNot(psiElement().afterLeaf("."))
        .accepts(position)) {
      PsiElement stmt = position.getParent().getParent();
      PsiIfStatement ifStatement = (PsiIfStatement) stmt.getParent();
      if (ifStatement.getElseBranch() == stmt || ifStatement.getThenBranch() == stmt) {
        return true;
      }
    }

    return false;
  }
  private void queueElement(
      @NotNull PsiElement child,
      final boolean whitespaceOptimizationAllowed,
      @NotNull PsiTreeChangeEvent event) {
    ApplicationManager.getApplication().assertIsDispatchThread();
    PsiFile file = event.getFile();
    if (file == null) file = child.getContainingFile();
    if (file == null) {
      myFileStatusMap.markAllFilesDirty(child);
      return;
    }

    if (!child.isValid()) return;

    PsiDocumentManagerImpl pdm = (PsiDocumentManagerImpl) PsiDocumentManager.getInstance(myProject);
    Document document = pdm.getCachedDocument(file);
    if (document != null) {
      if (pdm.getSynchronizer().getTransaction(document) == null) {
        // content reload, language level change or some other big change
        myFileStatusMap.markAllFilesDirty(child);
        return;
      }

      List<Pair<PsiElement, Boolean>> toUpdate = changedElements.get(document);
      if (toUpdate == null) {
        toUpdate = new SmartList<>();
        changedElements.put(document, toUpdate);
      }
      toUpdate.add(Pair.create(child, whitespaceOptimizationAllowed));
    }
  }
  private static boolean shouldInsertParentheses(PsiClass psiClass, PsiElement position) {
    final PsiJavaCodeReferenceElement ref =
        PsiTreeUtil.getParentOfType(position, PsiJavaCodeReferenceElement.class);
    if (ref == null) {
      return false;
    }

    final PsiReferenceParameterList parameterList = ref.getParameterList();
    if (parameterList != null && parameterList.getTextLength() > 0) {
      return false;
    }

    final PsiElement prevElement = FilterPositionUtil.searchNonSpaceNonCommentBack(ref);
    if (prevElement != null && prevElement.getParent() instanceof PsiNewExpression) {

      Set<PsiType> expectedTypes = new HashSet<PsiType>();
      for (ExpectedTypeInfo info :
          ExpectedTypesProvider.getExpectedTypes((PsiExpression) prevElement.getParent(), true)) {
        expectedTypes.add(info.getType());
      }

      return JavaCompletionUtil.isDefinitelyExpected(psiClass, expectedTypes, position);
    }

    return false;
  }
  public AddModuleDependencyFix(
      Module currentModule, VirtualFile classVFile, PsiClass[] classes, PsiReference reference) {
    final PsiElement psiElement = reference.getElement();
    final Project project = psiElement.getProject();
    final JavaPsiFacade facade = JavaPsiFacade.getInstance(project);
    final ProjectFileIndex fileIndex = ProjectRootManager.getInstance(project).getFileIndex();

    for (PsiClass aClass : classes) {
      if (!facade.getResolveHelper().isAccessible(aClass, psiElement, aClass)) continue;
      PsiFile psiFile = aClass.getContainingFile();
      if (psiFile == null) continue;
      VirtualFile virtualFile = psiFile.getVirtualFile();
      if (virtualFile == null) continue;
      final Module classModule = fileIndex.getModuleForFile(virtualFile);
      if (classModule != null
          && classModule != currentModule
          && !ModuleRootManager.getInstance(currentModule).isDependsOn(classModule)) {
        myModules.add(classModule);
      }
    }
    myCurrentModule = currentModule;
    myClassVFile = classVFile;
    myClasses = classes;
    myReference = reference;
  }
  @Nullable
  private String verifyInnerClassDestination() {
    PsiClass targetClass = findTargetClass();
    if (targetClass == null) return null;

    for (PsiElement element : myElementsToMove) {
      if (PsiTreeUtil.isAncestor(element, targetClass, false)) {
        return RefactoringBundle.message("move.class.to.inner.move.to.self.error");
      }
      final Language targetClassLanguage = targetClass.getLanguage();
      if (!element.getLanguage().equals(targetClassLanguage)) {
        return RefactoringBundle.message(
            "move.to.different.language",
            UsageViewUtil.getType(element),
            ((PsiClass) element).getQualifiedName(),
            targetClass.getQualifiedName());
      }
      if (element.getLanguage().equals(Language.findLanguageByID("Groovy"))) {
        return RefactoringBundle.message("dont.support.inner.classes", "Groovy");
      }
    }

    while (targetClass != null) {
      if (targetClass.getContainingClass() != null
          && !targetClass.hasModifierProperty(PsiModifier.STATIC)) {
        return RefactoringBundle.message("move.class.to.inner.nonstatic.error");
      }
      targetClass = targetClass.getContainingClass();
    }

    return null;
  }
예제 #30
0
  private static BraceStatus checkForMovableDownClosingBrace(
      @NotNull PsiElement closingBrace,
      @NotNull PsiElement block,
      @NotNull Editor editor,
      @NotNull MoveInfo info) {
    PsiElement current = block;
    PsiElement nextElement = null;
    PsiElement nextExpression = null;
    do {
      PsiElement sibling = firstNonWhiteElement(current.getNextSibling(), true);
      if (sibling != null && nextElement == null) {
        nextElement = sibling;
      }

      if (sibling instanceof JetExpression) {
        nextExpression = sibling;
        break;
      }

      current = current.getParent();
    } while (current != null && !(PsiTreeUtil.instanceOf(current, BLOCKLIKE_ELEMENT_CLASSES)));

    if (nextExpression == null) return BraceStatus.NOT_MOVABLE;

    Document doc = editor.getDocument();

    info.toMove = new LineRange(closingBrace, closingBrace, doc);
    info.toMove2 = new LineRange(nextElement, nextExpression);
    info.indentSource = true;

    return BraceStatus.MOVABLE;
  }