void loadFromEditor(@NotNull Editor editor) {
    assertDispatchThread();
    LOG.assertTrue(!editor.isDisposed());
    clear();

    PsiDocumentManager documentManager = PsiDocumentManager.getInstance(myProject);
    documentManager.commitDocument(editor.getDocument());
    PsiFile file = documentManager.getPsiFile(editor.getDocument());

    SmartPointerManager smartPointerManager = SmartPointerManager.getInstance(myProject);
    EditorFoldingInfo info = EditorFoldingInfo.get(editor);
    FoldRegion[] foldRegions = editor.getFoldingModel().getAllFoldRegions();
    for (FoldRegion region : foldRegions) {
      if (!region.isValid()) continue;
      PsiElement element = info.getPsiElement(region);
      boolean expanded = region.isExpanded();
      boolean collapseByDefault =
          element != null
              && FoldingPolicy.isCollapseByDefault(element)
              && !FoldingUtil.caretInsideRange(editor, TextRange.create(region));
      if (collapseByDefault == expanded || element == null) {
        FoldingInfo fi = new FoldingInfo(region.getPlaceholderText(), expanded);
        if (element != null) {
          myPsiElements.add(smartPointerManager.createSmartPsiElementPointer(element, file));
          element.putUserData(FOLDING_INFO_KEY, fi);
        } else if (region.isValid()) {
          myRangeMarkers.add(region);
          region.putUserData(FOLDING_INFO_KEY, fi);
        }
      }
    }
  }
  private void altCommitToOriginal(@NotNull DocumentEvent e) {
    final PsiFile origPsiFile =
        PsiDocumentManager.getInstance(myProject).getPsiFile(myOrigDocument);
    String newText = myNewDocument.getText();
    // prepare guarded blocks
    LinkedHashMap<String, String> replacementMap = new LinkedHashMap<String, String>();
    int count = 0;
    for (RangeMarker o : ContainerUtil.reverse(((DocumentEx) myNewDocument).getGuardedBlocks())) {
      String replacement = o.getUserData(REPLACEMENT_KEY);
      String tempText = "REPLACE" + (count++) + Long.toHexString(StringHash.calc(replacement));
      newText =
          newText.substring(0, o.getStartOffset()) + tempText + newText.substring(o.getEndOffset());
      replacementMap.put(tempText, replacement);
    }
    // run preformat processors
    final int hostStartOffset = myAltFullRange.getStartOffset();
    myEditor.getCaretModel().moveToOffset(hostStartOffset);
    for (CopyPastePreProcessor preProcessor :
        Extensions.getExtensions(CopyPastePreProcessor.EP_NAME)) {
      newText = preProcessor.preprocessOnPaste(myProject, origPsiFile, myEditor, newText, null);
    }
    myOrigDocument.replaceString(hostStartOffset, myAltFullRange.getEndOffset(), newText);
    // replace temp strings for guarded blocks
    for (String tempText : replacementMap.keySet()) {
      int idx =
          CharArrayUtil.indexOf(
              myOrigDocument.getCharsSequence(),
              tempText,
              hostStartOffset,
              myAltFullRange.getEndOffset());
      myOrigDocument.replaceString(idx, idx + tempText.length(), replacementMap.get(tempText));
    }
    // JAVA: fix occasional char literal concatenation
    fixDocumentQuotes(myOrigDocument, hostStartOffset - 1);
    fixDocumentQuotes(myOrigDocument, myAltFullRange.getEndOffset());

    // reformat
    PsiDocumentManager.getInstance(myProject).commitDocument(myOrigDocument);
    Runnable task =
        () -> {
          try {
            CodeStyleManager.getInstance(myProject)
                .reformatRange(origPsiFile, hostStartOffset, myAltFullRange.getEndOffset(), true);
          } catch (IncorrectOperationException e1) {
            // LOG.error(e);
          }
        };
    DocumentUtil.executeInBulk(myOrigDocument, true, task);

    PsiElement newInjected =
        InjectedLanguageManager.getInstance(myProject)
            .findInjectedElementAt(origPsiFile, hostStartOffset);
    DocumentWindow documentWindow =
        newInjected == null ? null : InjectedLanguageUtil.getDocumentWindow(newInjected);
    if (documentWindow != null) {
      myEditor.getCaretModel().moveToOffset(documentWindow.injectedToHost(e.getOffset()));
      myEditor.getScrollingModel().scrollToCaret(ScrollType.MAKE_VISIBLE);
    }
  }
 private void commitToOriginalInner() {
   final String text = myNewDocument.getText();
   final Map<
           PsiLanguageInjectionHost,
           Set<Trinity<RangeMarker, RangeMarker, SmartPsiElementPointer>>>
       map =
           ContainerUtil.classify(
               myMarkers.iterator(),
               new Convertor<
                   Trinity<RangeMarker, RangeMarker, SmartPsiElementPointer>,
                   PsiLanguageInjectionHost>() {
                 @Override
                 public PsiLanguageInjectionHost convert(
                     final Trinity<RangeMarker, RangeMarker, SmartPsiElementPointer> o) {
                   final PsiElement element = o.third.getElement();
                   return (PsiLanguageInjectionHost) element;
                 }
               });
   PsiDocumentManager documentManager = PsiDocumentManager.getInstance(myProject);
   documentManager.commitDocument(myOrigDocument); // commit here and after each manipulator update
   int localInsideFileCursor = 0;
   for (PsiLanguageInjectionHost host : map.keySet()) {
     if (host == null) continue;
     String hostText = host.getText();
     ProperTextRange insideHost = null;
     StringBuilder sb = new StringBuilder();
     for (Trinity<RangeMarker, RangeMarker, SmartPsiElementPointer> entry : map.get(host)) {
       RangeMarker origMarker = entry.first; // check for validity?
       int hostOffset = host.getTextRange().getStartOffset();
       ProperTextRange localInsideHost =
           new ProperTextRange(
               origMarker.getStartOffset() - hostOffset, origMarker.getEndOffset() - hostOffset);
       RangeMarker rangeMarker = entry.second;
       ProperTextRange localInsideFile =
           new ProperTextRange(
               Math.max(localInsideFileCursor, rangeMarker.getStartOffset()),
               rangeMarker.getEndOffset());
       if (insideHost != null) {
         // append unchanged inter-markers fragment
         sb.append(
             hostText.substring(insideHost.getEndOffset(), localInsideHost.getStartOffset()));
       }
       sb.append(
           localInsideFile.getEndOffset() <= text.length() && !localInsideFile.isEmpty()
               ? localInsideFile.substring(text)
               : "");
       localInsideFileCursor = localInsideFile.getEndOffset();
       insideHost = insideHost == null ? localInsideHost : insideHost.union(localInsideHost);
     }
     assert insideHost != null;
     ElementManipulators.getManipulator(host).handleContentChange(host, insideHost, sb.toString());
     documentManager.commitDocument(myOrigDocument);
   }
 }
  private CodeFormatterFacade getFormatterFacade(final FileViewProvider viewProvider) {
    final CodeStyleSettings styleSettings =
        CodeStyleSettingsManager.getSettings(myPsiManager.getProject());
    final PsiDocumentManager documentManager =
        PsiDocumentManager.getInstance(myPsiManager.getProject());
    final Document document = viewProvider.getDocument();
    final CodeFormatterFacade codeFormatter = new CodeFormatterFacade(styleSettings);

    documentManager.commitDocument(document);
    return codeFormatter;
  }
예제 #5
0
  public static TextWithImports getEditorText(final Editor editor) {
    if (editor == null) {
      return null;
    }
    final Project project = editor.getProject();
    if (project == null) return null;

    String defaultExpression = editor.getSelectionModel().getSelectedText();
    if (defaultExpression == null) {
      int offset = editor.getCaretModel().getOffset();
      PsiFile psiFile = PsiDocumentManager.getInstance(project).getPsiFile(editor.getDocument());
      if (psiFile != null) {
        PsiElement elementAtCursor = psiFile.findElementAt(offset);
        if (elementAtCursor != null) {
          final EditorTextProvider textProvider =
              EditorTextProvider.EP.forLanguage(elementAtCursor.getLanguage());
          if (textProvider != null) {
            final TextWithImports editorText = textProvider.getEditorText(elementAtCursor);
            if (editorText != null) return editorText;
          }
        }
      }
    } else {
      return new TextWithImportsImpl(CodeFragmentKind.EXPRESSION, defaultExpression);
    }
    return null;
  }
 @Override
 public int injectedToHost(@NotNull PsiElement element, int offset) {
   PsiFile file = element.getContainingFile();
   if (file == null) return offset;
   Document document = PsiDocumentManager.getInstance(file.getProject()).getCachedDocument(file);
   if (!(document instanceof DocumentWindowImpl)) return offset;
   DocumentWindowImpl documentWindow = (DocumentWindowImpl) document;
   return documentWindow.injectedToHost(offset);
 }
 public static PsiElement findInjectedElementNoCommit(
     @NotNull PsiFile hostFile, final int offset) {
   if (hostFile instanceof PsiCompiledElement) return null;
   Project project = hostFile.getProject();
   if (InjectedLanguageManager.getInstance(project).isInjectedFragment(hostFile)) return null;
   final PsiDocumentManager documentManager = PsiDocumentManager.getInstance(project);
   Trinity<PsiElement, PsiElement, Language> result = tryOffset(hostFile, offset, documentManager);
   PsiElement injected = result.first;
   return injected;
 }
  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();
  }
예제 #9
0
  public static void doTearDown() throws Exception {
    UsefulTestCase.doPostponedFormatting(ourProject);

    LookupManager.getInstance(ourProject).hideActiveLookup();

    InspectionProfileManager.getInstance().deleteProfile(PROFILE);
    assertNotNull("Application components damaged", ProjectManager.getInstance());

    ApplicationManager.getApplication()
        .runWriteAction(
            new Runnable() {
              public void run() {
                try {
                  final VirtualFile[] children = ourSourceRoot.getChildren();
                  for (VirtualFile child : children) {
                    child.delete(this);
                  }
                } catch (IOException e) {
                  //noinspection CallToPrintStackTrace
                  e.printStackTrace();
                }
                FileDocumentManager manager = FileDocumentManager.getInstance();
                if (manager instanceof FileDocumentManagerImpl) {
                  ((FileDocumentManagerImpl) manager).dropAllUnsavedDocuments();
                }
              }
            });
    //    final Project[] openProjects = ProjectManagerEx.getInstanceEx().getOpenProjects();
    //    assertTrue(Arrays.asList(openProjects).contains(ourProject));
    assertFalse(PsiManager.getInstance(getProject()).isDisposed());
    if (!ourAssertionsInTestDetected) {
      if (IdeaLogger.ourErrorsOccurred != null) {
        throw IdeaLogger.ourErrorsOccurred;
      }
      // assertTrue("Logger errors occurred. ", IdeaLogger.ourErrorsOccurred == null);
    }
    ((PsiDocumentManagerImpl) PsiDocumentManager.getInstance(getProject()))
        .clearUncommitedDocuments();

    ((UndoManagerImpl) UndoManager.getGlobalInstance()).dropHistoryInTests();

    ProjectManagerEx.getInstanceEx().setCurrentTestProject(null);
    ourApplication.setDataProvider(null);
    ourTestCase = null;
    ((PsiManagerImpl) ourPsiManager).cleanupForNextTest();

    final Editor[] allEditors = EditorFactory.getInstance().getAllEditors();
    if (allEditors.length > 0) {
      for (Editor allEditor : allEditors) {
        EditorFactory.getInstance().releaseEditor(allEditor);
      }
      fail("Unreleased editors: " + allEditors.length);
    }
  }
 @Override
 @NotNull
 public TextRange injectedToHost(
     @NotNull PsiElement injectedContext, @NotNull TextRange injectedTextRange) {
   ProperTextRange.assertProperRange(injectedTextRange);
   PsiFile file = injectedContext.getContainingFile();
   if (file == null) return injectedTextRange;
   Document document = PsiDocumentManager.getInstance(file.getProject()).getCachedDocument(file);
   if (!(document instanceof DocumentWindowImpl)) return injectedTextRange;
   DocumentWindowImpl documentWindow = (DocumentWindowImpl) document;
   return documentWindow.injectedToHost(injectedTextRange);
 }
  // need to shorten references in type argument list
  public static void shortenReference(final PsiFile file, final int offset)
      throws IncorrectOperationException {
    Project project = file.getProject();
    final PsiDocumentManager manager = PsiDocumentManager.getInstance(project);
    Document document = manager.getDocument(file);
    if (document == null) {
      PsiUtilCore.ensureValid(file);
      LOG.error("No document for " + file);
      return;
    }

    manager.commitDocument(document);
    final PsiReference ref = file.findReferenceAt(offset);
    if (ref != null) {
      PsiElement element = ref.getElement();
      if (element != null) {
        JavaCodeStyleManager.getInstance(project).shortenClassReferences(element);
        PsiDocumentManager.getInstance(project).doPostponedOperationsAndUnblockDocument(document);
      }
    }
  }
 public static PsiFile getTopLevelFile(@NotNull PsiElement element) {
   PsiFile containingFile = element.getContainingFile();
   if (containingFile == null) return null;
   Document document =
       PsiDocumentManager.getInstance(element.getProject()).getCachedDocument(containingFile);
   if (document instanceof DocumentWindow) {
     PsiElement host =
         InjectedLanguageManager.getInstance(containingFile.getProject())
             .getInjectionHost(containingFile);
     if (host != null) containingFile = host.getContainingFile();
   }
   return containingFile;
 }
 // consider injected elements
 public static PsiElement findElementAtNoCommit(@NotNull PsiFile file, int offset) {
   FileViewProvider viewProvider = file.getViewProvider();
   Trinity<PsiElement, PsiElement, Language> result = null;
   if (!(viewProvider instanceof InjectedFileViewProvider)) {
     PsiDocumentManager documentManager = PsiDocumentManager.getInstance(file.getProject());
     result = tryOffset(file, offset, documentManager);
     PsiElement injected = result.first;
     if (injected != null) {
       return injected;
     }
   }
   Language baseLanguage = viewProvider.getBaseLanguage();
   if (result != null && baseLanguage == result.third) {
     return result.second; // already queried
   }
   return viewProvider.findElementAt(offset, baseLanguage);
 }
예제 #14
0
  public static List<PsiLambdaExpression> collectLambdas(
      @NotNull SourcePosition position, final boolean onlyOnTheLine) {
    ApplicationManager.getApplication().assertReadAccessAllowed();
    PsiFile file = position.getFile();
    final int line = position.getLine();
    final Document document = PsiDocumentManager.getInstance(file.getProject()).getDocument(file);
    if (document == null || line >= document.getLineCount()) {
      return Collections.emptyList();
    }
    PsiElement element = position.getElementAt();
    final TextRange lineRange = DocumentUtil.getLineTextRange(document, line);
    do {
      PsiElement parent = element.getParent();
      if (parent == null || (parent.getTextOffset() < lineRange.getStartOffset())) {
        break;
      }
      element = parent;
    } while (true);

    final List<PsiLambdaExpression> lambdas = new ArrayList<PsiLambdaExpression>(3);
    final PsiElementVisitor lambdaCollector =
        new JavaRecursiveElementVisitor() {
          @Override
          public void visitLambdaExpression(PsiLambdaExpression expression) {
            super.visitLambdaExpression(expression);
            if (!onlyOnTheLine || getFirstElementOnTheLine(expression, document, line) != null) {
              lambdas.add(expression);
            }
          }
        };
    element.accept(lambdaCollector);
    // add initial lambda if we're inside already
    PsiElement method = getContainingMethod(element);
    if (method instanceof PsiLambdaExpression) {
      lambdas.add((PsiLambdaExpression) method);
    }
    for (PsiElement sibling = getNextElement(element);
        sibling != null;
        sibling = getNextElement(sibling)) {
      if (!intersects(lineRange, sibling)) {
        break;
      }
      sibling.accept(lambdaCollector);
    }
    return lambdas;
  }
  public static boolean insertTail(
      InsertionContext context, LookupElement item, TailType tailType, boolean hasTail) {
    TailType toInsert = tailType;
    LookupItem<?> lookupItem = item.as(LookupItem.CLASS_CONDITION_KEY);
    if (lookupItem == null
        || lookupItem.getAttribute(LookupItem.TAIL_TYPE_ATTR) != TailType.UNKNOWN) {
      if (!hasTail
          && item.getObject() instanceof PsiMethod
          && ((PsiMethod) item.getObject()).getReturnType() == PsiType.VOID) {
        PsiDocumentManager.getInstance(context.getProject()).commitAllDocuments();
        if (psiElement()
            .beforeLeaf(psiElement().withText("."))
            .accepts(context.getFile().findElementAt(context.getTailOffset() - 1))) {
          return false;
        }

        boolean insertAdditionalSemicolon = true;
        final PsiReferenceExpression referenceExpression =
            PsiTreeUtil.getTopmostParentOfType(
                context.getFile().findElementAt(context.getStartOffset()),
                PsiReferenceExpression.class);
        if (referenceExpression instanceof PsiMethodReferenceExpression
            && LambdaHighlightingUtil.insertSemicolon(referenceExpression.getParent())) {
          insertAdditionalSemicolon = false;
        } else if (referenceExpression != null) {
          PsiElement parent = referenceExpression.getParent();
          if (parent instanceof PsiMethodCallExpression) {
            parent = parent.getParent();
          }
          if (parent instanceof PsiLambdaExpression
              && !LambdaHighlightingUtil.insertSemicolonAfter((PsiLambdaExpression) parent)) {
            insertAdditionalSemicolon = false;
          }
        }
        if (insertAdditionalSemicolon) {
          toInsert = TailType.SEMICOLON;
        }
      }
    }
    toInsert.processTail(context.getEditor(), context.getTailOffset());
    return true;
  }
  private boolean findUsageInFile(@NotNull FileEditor editor, @NotNull FileSearchScope direction) {
    PsiElement[] elements = restorePsiElements(myLastSearchInFileData, true);
    if (elements == null) return false;
    if (elements.length == 0) return true; // all elements have invalidated

    UsageInfoToUsageConverter.TargetElementsDescriptor descriptor =
        new UsageInfoToUsageConverter.TargetElementsDescriptor(elements);

    // todo
    TextEditor textEditor = (TextEditor) editor;
    Document document = textEditor.getEditor().getDocument();
    PsiFile psiFile = PsiDocumentManager.getInstance(myProject).getPsiFile(document);
    if (psiFile == null) return false;

    final FindUsagesHandler handler = getFindUsagesHandler(elements[0], false);
    if (handler == null) return false;
    findUsagesInEditor(
        descriptor, handler, psiFile, direction, myLastSearchInFileData.myOptions, textEditor);
    return true;
  }
 public static Editor openEditorFor(@NotNull PsiFile file, @NotNull Project project) {
   Document document = PsiDocumentManager.getInstance(project).getDocument(file);
   // may return editor injected in current selection in the host editor, not for the file passed
   // as argument
   VirtualFile virtualFile = file.getVirtualFile();
   if (virtualFile == null) {
     return null;
   }
   if (virtualFile instanceof VirtualFileWindow) {
     virtualFile = ((VirtualFileWindow) virtualFile).getDelegate();
   }
   Editor editor =
       FileEditorManager.getInstance(project)
           .openTextEditor(new OpenFileDescriptor(project, virtualFile, -1), false);
   if (editor == null || editor instanceof EditorWindow || editor.isDisposed()) return editor;
   if (document instanceof DocumentWindowImpl) {
     return EditorWindow.create((DocumentWindowImpl) document, (EditorImpl) editor, file);
   }
   return editor;
 }
  public static void renameNonCodeUsages(
      @NotNull Project project, @NotNull NonCodeUsageInfo[] usages) {
    PsiDocumentManager.getInstance(project).commitAllDocuments();
    Map<Document, List<UsageOffset>> docsToOffsetsMap = new HashMap<Document, List<UsageOffset>>();
    final PsiDocumentManager psiDocumentManager = PsiDocumentManager.getInstance(project);
    for (NonCodeUsageInfo usage : usages) {
      PsiElement element = usage.getElement();

      if (element == null) continue;
      element = CodeInsightUtilBase.forcePsiPostprocessAndRestoreElement(element, true);
      if (element == null) continue;

      final ProperTextRange rangeInElement = usage.getRangeInElement();
      if (rangeInElement == null) continue;

      final PsiFile containingFile = element.getContainingFile();
      final Document document = psiDocumentManager.getDocument(containingFile);

      final Segment segment = usage.getSegment();
      LOG.assertTrue(segment != null);
      int fileOffset = segment.getStartOffset();

      List<UsageOffset> list = docsToOffsetsMap.get(document);
      if (list == null) {
        list = new ArrayList<UsageOffset>();
        docsToOffsetsMap.put(document, list);
      }

      list.add(new UsageOffset(fileOffset, fileOffset + rangeInElement.getLength(), usage.newText));
    }

    for (Document document : docsToOffsetsMap.keySet()) {
      List<UsageOffset> list = docsToOffsetsMap.get(document);
      LOG.assertTrue(list != null, document);
      UsageOffset[] offsets = list.toArray(new UsageOffset[list.size()]);
      Arrays.sort(offsets);

      for (int i = offsets.length - 1; i >= 0; i--) {
        UsageOffset usageOffset = offsets[i];
        document.replaceString(usageOffset.startOffset, usageOffset.endOffset, usageOffset.newText);
      }
      PsiDocumentManager.getInstance(project).commitDocument(document);
    }
    PsiDocumentManager.getInstance(project).commitAllDocuments();
  }
 @NotNull
 public static Editor getInjectedEditorForInjectedFile(
     @NotNull Editor hostEditor, @Nullable final PsiFile injectedFile) {
   if (injectedFile == null || hostEditor instanceof EditorWindow || hostEditor.isDisposed())
     return hostEditor;
   Project project = hostEditor.getProject();
   if (project == null) project = injectedFile.getProject();
   Document document = PsiDocumentManager.getInstance(project).getDocument(injectedFile);
   if (!(document instanceof DocumentWindowImpl)) return hostEditor;
   DocumentWindowImpl documentWindow = (DocumentWindowImpl) document;
   SelectionModel selectionModel = hostEditor.getSelectionModel();
   if (selectionModel.hasSelection()) {
     int selstart = selectionModel.getSelectionStart();
     int selend = selectionModel.getSelectionEnd();
     if (!documentWindow.containsRange(selstart, selend)) {
       // selection spreads out the injected editor range
       return hostEditor;
     }
   }
   if (!documentWindow.isValid())
     return hostEditor; // since the moment we got hold of injectedFile and this moment call,
                        // document may have been dirtied
   return EditorWindow.create(documentWindow, (EditorImpl) hostEditor, injectedFile);
 }
 private void commitToOriginal(final DocumentEvent e) {
   VirtualFile origVirtualFile = PsiUtilCore.getVirtualFile(myNewFile.getContext());
   myCommittingToOriginal = true;
   try {
     if (origVirtualFile == null
         || !ReadonlyStatusHandler.getInstance(myProject)
             .ensureFilesWritable(origVirtualFile)
             .hasReadonlyFiles()) {
       PostprocessReformattingAspect.getInstance(myProject)
           .disablePostprocessFormattingInside(
               () -> {
                 if (myAltFullRange != null) {
                   altCommitToOriginal(e);
                   return;
                 }
                 commitToOriginalInner();
               });
       PsiDocumentManager.getInstance(myProject)
           .doPostponedOperationsAndUnblockDocument(myOrigDocument);
     }
   } finally {
     myCommittingToOriginal = false;
   }
 }
예제 #21
0
 protected static Document getDocument(final PsiFile file) {
   return PsiDocumentManager.getInstance(getProject()).getDocument(file);
 }
예제 #22
0
 protected static void commitAllDocuments() {
   PsiDocumentManager.getInstance(getProject()).commitAllDocuments();
 }
예제 #23
0
 protected static void commitDocument(final Document document) {
   PsiDocumentManager.getInstance(getProject()).commitDocument(document);
 }
예제 #24
0
  public static void doSetup(
      final LightProjectDescriptor descriptor,
      final LocalInspectionTool[] localInspectionTools,
      final Map<String, InspectionTool> availableInspectionTools)
      throws Exception {
    assertNull(
        "Previous test "
            + ourTestCase
            + " hasn't called tearDown(). Probably overriden without super call.",
        ourTestCase);
    IdeaLogger.ourErrorsOccurred = null;

    if (ourProject == null || !ourProjectDescriptor.equals(descriptor)) {
      initProject(descriptor);
    }

    ProjectManagerEx.getInstanceEx().setCurrentTestProject(ourProject);

    ((PsiDocumentManagerImpl) PsiDocumentManager.getInstance(getProject()))
        .clearUncommitedDocuments();

    for (LocalInspectionTool tool : localInspectionTools) {
      enableInspectionTool(availableInspectionTools, new LocalInspectionToolWrapper(tool));
    }

    final InspectionProfileImpl profile =
        new InspectionProfileImpl("Configurable") {
          @NotNull
          public InspectionProfileEntry[] getInspectionTools(PsiElement element) {
            if (availableInspectionTools != null) {
              final Collection<InspectionTool> tools = availableInspectionTools.values();
              return tools.toArray(new InspectionTool[tools.size()]);
            }
            return new InspectionTool[0];
          }

          @Override
          public List<ToolsImpl> getAllEnabledInspectionTools() {
            List<ToolsImpl> result = new ArrayList<ToolsImpl>();
            for (InspectionProfileEntry entry : getInspectionTools(null)) {
              result.add(new ToolsImpl(entry, entry.getDefaultLevel(), true));
            }
            return result;
          }

          public boolean isToolEnabled(HighlightDisplayKey key, PsiElement element) {
            return key != null && availableInspectionTools.containsKey(key.toString());
          }

          public HighlightDisplayLevel getErrorLevel(
              @NotNull HighlightDisplayKey key, PsiElement element) {
            InspectionTool localInspectionTool = availableInspectionTools.get(key.toString());
            return localInspectionTool != null
                ? localInspectionTool.getDefaultLevel()
                : HighlightDisplayLevel.WARNING;
          }

          public InspectionTool getInspectionTool(
              @NotNull String shortName, @NotNull PsiElement element) {
            if (availableInspectionTools.containsKey(shortName)) {
              return availableInspectionTools.get(shortName);
            }
            return null;
          }
        };
    final InspectionProfileManager inspectionProfileManager =
        InspectionProfileManager.getInstance();
    inspectionProfileManager.addProfile(profile);
    inspectionProfileManager.setRootProfile(profile.getName());
    InspectionProjectProfileManager.getInstance(getProject()).updateProfile(profile);
    InspectionProjectProfileManager.getInstance(getProject()).setProjectProfile(profile.getName());

    assertFalse(getPsiManager().isDisposed());

    CodeStyleSettingsManager.getInstance(getProject())
        .setTemporarySettings(new CodeStyleSettings());
  }
  QuickEditHandler(
      Project project,
      @NotNull PsiFile injectedFile,
      final PsiFile origFile,
      Editor editor,
      QuickEditAction action) {
    myProject = project;
    myEditor = editor;
    myAction = action;
    myOrigDocument = editor.getDocument();
    Place shreds = InjectedLanguageUtil.getShreds(injectedFile);
    FileType fileType = injectedFile.getFileType();
    Language language = injectedFile.getLanguage();
    PsiLanguageInjectionHost.Shred firstShred = ContainerUtil.getFirstItem(shreds);

    PsiFileFactory factory = PsiFileFactory.getInstance(project);
    String text = InjectedLanguageManager.getInstance(project).getUnescapedText(injectedFile);
    String newFileName =
        StringUtil.notNullize(language.getDisplayName(), "Injected")
            + " Fragment "
            + "("
            + origFile.getName()
            + ":"
            + firstShred.getHost().getTextRange().getStartOffset()
            + ")"
            + "."
            + fileType.getDefaultExtension();

    // preserve \r\n as it is done in MultiHostRegistrarImpl
    myNewFile = factory.createFileFromText(newFileName, language, text, true, false);
    myNewVirtualFile = ObjectUtils.assertNotNull((LightVirtualFile) myNewFile.getVirtualFile());
    myNewVirtualFile.setOriginalFile(origFile.getVirtualFile());

    assert myNewFile != null : "PSI file is null";
    assert myNewFile.getTextLength() == myNewVirtualFile.getContent().length()
        : "PSI / Virtual file text mismatch";

    myNewVirtualFile.setOriginalFile(origFile.getVirtualFile());
    // suppress possible errors as in injected mode
    myNewFile.putUserData(
        InjectedLanguageUtil.FRANKENSTEIN_INJECTION,
        injectedFile.getUserData(InjectedLanguageUtil.FRANKENSTEIN_INJECTION));
    myNewFile.putUserData(FileContextUtil.INJECTED_IN_ELEMENT, shreds.getHostPointer());
    myNewDocument = PsiDocumentManager.getInstance(project).getDocument(myNewFile);
    assert myNewDocument != null;
    EditorActionManager.getInstance()
        .setReadonlyFragmentModificationHandler(myNewDocument, new MyQuietHandler());
    myOrigCreationStamp =
        myOrigDocument.getModificationStamp(); // store creation stamp for UNDO tracking
    myOrigDocument.addDocumentListener(this, this);
    myNewDocument.addDocumentListener(this, this);
    EditorFactory editorFactory = ObjectUtils.assertNotNull(EditorFactory.getInstance());
    // not FileEditorManager listener because of RegExp checker and alike
    editorFactory.addEditorFactoryListener(
        new EditorFactoryAdapter() {
          int useCount;

          @Override
          public void editorCreated(@NotNull EditorFactoryEvent event) {
            if (event.getEditor().getDocument() != myNewDocument) return;
            useCount++;
          }

          @Override
          public void editorReleased(@NotNull EditorFactoryEvent event) {
            if (event.getEditor().getDocument() != myNewDocument) return;
            if (--useCount > 0) return;
            if (Boolean.TRUE.equals(
                myNewVirtualFile.getUserData(FileEditorManagerImpl.CLOSING_TO_REOPEN))) return;

            Disposer.dispose(QuickEditHandler.this);
          }
        },
        this);

    if ("JAVA".equals(firstShred.getHost().getLanguage().getID())) {
      PsiLanguageInjectionHost.Shred lastShred = ContainerUtil.getLastItem(shreds);
      myAltFullRange =
          myOrigDocument.createRangeMarker(
              firstShred.getHostRangeMarker().getStartOffset(),
              lastShred.getHostRangeMarker().getEndOffset());
      myAltFullRange.setGreedyToLeft(true);
      myAltFullRange.setGreedyToRight(true);

      initGuardedBlocks(shreds);
      myInjectedFile = null;
    } else {
      initMarkers(shreds);
      myAltFullRange = null;
      myInjectedFile = injectedFile;
    }
  }
  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;
  }
  @Override
  public void writeExternal(Element element) throws WriteExternalException {
    PsiDocumentManager.getInstance(myProject).commitAllDocuments();

    if (myPsiElements.isEmpty() && myRangeMarkers.isEmpty() && mySerializedElements.isEmpty()) {
      throw new WriteExternalException();
    }

    if (mySerializedElements.isEmpty()) {
      for (SmartPsiElementPointer<PsiElement> ptr : myPsiElements) {
        PsiElement psiElement = ptr.getElement();
        if (psiElement == null || !psiElement.isValid()) {
          continue;
        }
        FoldingInfo fi = psiElement.getUserData(FOLDING_INFO_KEY);
        boolean state = fi != null && fi.expanded;
        String signature = FoldingPolicy.getSignature(psiElement);
        if (signature == null) {
          continue;
        }

        PsiFile containingFile = psiElement.getContainingFile();
        PsiElement restoredElement = FoldingPolicy.restoreBySignature(containingFile, signature);
        if (!psiElement.equals(restoredElement)) {
          StringBuilder trace = new StringBuilder();
          PsiElement restoredAgain =
              FoldingPolicy.restoreBySignature(containingFile, signature, trace);
          LOG.error(
              "element: "
                  + psiElement
                  + "("
                  + psiElement.getText()
                  + "); restoredElement: "
                  + restoredElement
                  + "; signature: '"
                  + signature
                  + "'; file: "
                  + containingFile
                  + "; injected: "
                  + InjectedLanguageManager.getInstance(myProject)
                      .isInjectedFragment(containingFile)
                  + "; languages: "
                  + containingFile.getViewProvider().getLanguages()
                  + "; restored again: "
                  + restoredAgain
                  + "; restore produces same results: "
                  + (restoredAgain == restoredElement)
                  + "; trace:\n"
                  + trace);
        }

        Element e = new Element(ELEMENT_TAG);
        e.setAttribute(SIGNATURE_ATT, signature);
        e.setAttribute(EXPANDED_ATT, Boolean.toString(state));
        element.addContent(e);
      }
    } else {
      // get back postponed state (before folding initialization)
      for (SerializedPsiElement entry : mySerializedElements) {
        Element e = new Element(ELEMENT_TAG);
        e.setAttribute(SIGNATURE_ATT, entry.mySerializedElement);
        e.setAttribute(EXPANDED_ATT, Boolean.toString(entry.myFoldingInfo.getExpanded()));
        element.addContent(e);
      }
    }
    String date = null;
    for (RangeMarker marker : myRangeMarkers) {
      FoldingInfo fi = marker.getUserData(FOLDING_INFO_KEY);
      boolean state = fi != null && fi.expanded;

      Element e = new Element(MARKER_TAG);
      if (date == null) {
        date = getTimeStamp();
      }
      if (date.isEmpty()) {
        continue;
      }

      e.setAttribute(DATE_ATT, date);
      e.setAttribute(EXPANDED_ATT, Boolean.toString(state));
      String signature =
          Integer.valueOf(marker.getStartOffset()) + ":" + Integer.valueOf(marker.getEndOffset());
      e.setAttribute(SIGNATURE_ATT, signature);
      String placeHolderText = fi == null ? DEFAULT_PLACEHOLDER : fi.placeHolder;
      e.setAttribute(PLACEHOLDER_ATT, placeHolderText);
      element.addContent(e);
    }
  }
  @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;
    }
  }
  private boolean addInjectedPsiHighlights(
      @NotNull PsiFile injectedPsi,
      TextAttributes injectedAttributes,
      @NotNull Collection<HighlightInfo> outInfos,
      @NotNull ProgressIndicator progress,
      @NotNull InjectedLanguageManager injectedLanguageManager) {
    DocumentWindow documentWindow =
        (DocumentWindow) PsiDocumentManager.getInstance(myProject).getCachedDocument(injectedPsi);
    if (documentWindow == null) return true;
    Place places = InjectedLanguageUtil.getShreds(injectedPsi);
    for (PsiLanguageInjectionHost.Shred place : places) {
      PsiLanguageInjectionHost host = place.getHost();
      if (host == null) continue;
      TextRange textRange =
          place.getRangeInsideHost().shiftRight(host.getTextRange().getStartOffset());
      if (textRange.isEmpty()) continue;
      String desc = injectedPsi.getLanguage().getDisplayName() + ": " + injectedPsi.getText();
      HighlightInfo.Builder builder =
          HighlightInfo.newHighlightInfo(HighlightInfoType.INJECTED_LANGUAGE_BACKGROUND)
              .range(textRange);
      if (injectedAttributes != null && InjectedLanguageUtil.isHighlightInjectionBackground(host)) {
        builder.textAttributes(injectedAttributes);
      }
      builder.unescapedToolTip(desc);
      HighlightInfo info = builder.createUnconditionally();
      info.setFromInjection(true);
      outInfos.add(info);
    }

    HighlightInfoHolder holder = createInfoHolder(injectedPsi);
    runHighlightVisitorsForInjected(injectedPsi, holder, progress);
    for (int i = 0; i < holder.size(); i++) {
      HighlightInfo info = holder.get(i);
      final int startOffset = documentWindow.injectedToHost(info.startOffset);
      final TextRange fixedTextRange = getFixedTextRange(documentWindow, startOffset);
      addPatchedInfos(
          info, injectedPsi, documentWindow, injectedLanguageManager, fixedTextRange, outInfos);
    }
    int injectedStart = holder.size();
    highlightInjectedSyntax(injectedPsi, holder);
    for (int i = injectedStart; i < holder.size(); i++) {
      HighlightInfo info = holder.get(i);
      final int startOffset = info.startOffset;
      final TextRange fixedTextRange = getFixedTextRange(documentWindow, startOffset);
      if (fixedTextRange == null) {
        info.setFromInjection(true);
        outInfos.add(info);
      } else {
        HighlightInfo patched =
            new HighlightInfo(
                info.forcedTextAttributes,
                info.forcedTextAttributesKey,
                info.type,
                fixedTextRange.getStartOffset(),
                fixedTextRange.getEndOffset(),
                info.getDescription(),
                info.getToolTip(),
                info.type.getSeverity(null),
                info.isAfterEndOfLine(),
                null,
                false,
                0,
                info.getProblemGroup(),
                info.getGutterIconRenderer());
        patched.setFromInjection(true);
        outInfos.add(patched);
      }
    }

    if (!isDumbMode()) {
      List<HighlightInfo> todos = new ArrayList<HighlightInfo>();
      highlightTodos(
          injectedPsi,
          injectedPsi.getText(),
          0,
          injectedPsi.getTextLength(),
          progress,
          myPriorityRange,
          todos,
          todos);
      for (HighlightInfo info : todos) {
        addPatchedInfos(info, injectedPsi, documentWindow, injectedLanguageManager, null, outInfos);
      }
    }
    advanceProgress(1);
    return true;
  }
예제 #30
0
  private static Trinity<PsiElement, TextRange, Value> getSelectedExpression(
      final Project project, final Editor editor, final Point point, final ValueHintType type) {
    final Ref<PsiElement> selectedExpression = Ref.create(null);
    final Ref<TextRange> currentRange = Ref.create(null);
    final Ref<Value> preCalculatedValue = Ref.create(null);

    PsiDocumentManager.getInstance(project)
        .commitAndRunReadAction(
            new Runnable() {
              public void run() {
                // Point -> offset
                final int offset = calculateOffset(editor, point);

                PsiFile psiFile =
                    PsiDocumentManager.getInstance(project).getPsiFile(editor.getDocument());

                if (psiFile == null || !psiFile.isValid()) return;

                int selectionStart = editor.getSelectionModel().getSelectionStart();
                int selectionEnd = editor.getSelectionModel().getSelectionEnd();

                if ((type == ValueHintType.MOUSE_CLICK_HINT
                        || type == ValueHintType.MOUSE_ALT_OVER_HINT)
                    && (selectionStart <= offset && offset <= selectionEnd)) {
                  PsiElement ctx =
                      (selectionStart > 0)
                          ? psiFile.findElementAt(selectionStart - 1)
                          : psiFile.findElementAt(selectionStart);
                  try {
                    String text = editor.getSelectionModel().getSelectedText();
                    if (text != null && ctx != null) {
                      selectedExpression.set(
                          JVMElementFactories.getFactory(ctx.getLanguage(), project)
                              .createExpressionFromText(text, ctx));
                      currentRange.set(
                          new TextRange(
                              editor.getSelectionModel().getSelectionStart(),
                              editor.getSelectionModel().getSelectionEnd()));
                    }
                  } catch (IncorrectOperationException ignored) {
                  }
                }

                if (currentRange.get() == null) {
                  PsiElement elementAtCursor = psiFile.findElementAt(offset);
                  if (elementAtCursor == null) {
                    return;
                  }
                  Pair<PsiElement, TextRange> pair =
                      findExpression(
                          elementAtCursor,
                          type == ValueHintType.MOUSE_CLICK_HINT
                              || type == ValueHintType.MOUSE_ALT_OVER_HINT);
                  if (pair == null) {
                    if (type == ValueHintType.MOUSE_OVER_HINT) {
                      final DebuggerSession debuggerSession =
                          DebuggerManagerEx.getInstanceEx(project)
                              .getContext()
                              .getDebuggerSession();
                      if (debuggerSession != null && debuggerSession.isPaused()) {
                        final Pair<Method, Value> lastExecuted =
                            debuggerSession.getProcess().getLastExecutedMethod();
                        if (lastExecuted != null) {
                          final Method method = lastExecuted.getFirst();
                          if (method != null) {
                            final Pair<PsiElement, TextRange> expressionPair =
                                findExpression(elementAtCursor, true);
                            if (expressionPair != null
                                && expressionPair.getFirst() instanceof PsiMethodCallExpression) {
                              final PsiMethodCallExpression methodCallExpression =
                                  (PsiMethodCallExpression) expressionPair.getFirst();
                              final PsiMethod psiMethod = methodCallExpression.resolveMethod();
                              if (psiMethod != null) {
                                final JVMName jvmSignature = JVMNameUtil.getJVMSignature(psiMethod);
                                try {
                                  if (method.name().equals(psiMethod.getName())
                                      && method
                                          .signature()
                                          .equals(
                                              jvmSignature.getName(debuggerSession.getProcess()))) {
                                    pair = expressionPair;
                                    preCalculatedValue.set(lastExecuted.getSecond());
                                  }
                                } catch (EvaluateException ignored) {
                                }
                              }
                            }
                          }
                        }
                      }
                    }
                  }
                  if (pair == null) {
                    return;
                  }
                  selectedExpression.set(pair.getFirst());
                  currentRange.set(pair.getSecond());
                }
              }
            });
    return Trinity.create(selectedExpression.get(), currentRange.get(), preCalculatedValue.get());
  }