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; }
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(); }
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); }
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; } }
protected static Document getDocument(final PsiFile file) { return PsiDocumentManager.getInstance(getProject()).getDocument(file); }
protected static void commitAllDocuments() { PsiDocumentManager.getInstance(getProject()).commitAllDocuments(); }
protected static void commitDocument(final Document document) { PsiDocumentManager.getInstance(getProject()).commitDocument(document); }
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; }
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()); }