Bulk PSI modification
As far as I understand, every time when i'm modifying PSI tree, it's being at least syncronized with document. I'ts fine and consistent, but if i need to make let's say 100 modifications in a row, process works really slow.
Question:
Is there a way to modify PSItree transactionally, make all modifications, than do all extra operations, like syncing with document?
Problem: i have a code style settings that may play with Perl code and modifications being done using Preformatter. And if file is large and there are lot of modifications, UI freezes for few seconds. Want to fix this.
请先登录再写评论。
It's not easy. Did you check in the profiler what exactly is slow? Postponed reformatting is invoked at the end of a write action, so if it's the culprit, you can try wrapping all modifications into one write action.
Here is a snapshot of pre-formatting of 100 items in 1 megabyte file
You could try wrapping apply() invocations in one pom transaction, see XmlTagImpl#collapseIfEmpty for an example. You'll probably need TreeAspect instead of XmlAspect.
Nope, same picture. Is there anyting to read about these Pom classes? Seems there is no JavaDoc on them. And, aside of the same performance, getting OOM exception after 60-th modification :)
Here is what i've done: https://github.com/hurricup/Perl5-IDEA/commit/7b458ff11f03ba12d3632b2455db97f6f9097f50
Pity. Unfortunately pom has no documentation except its source code :(
Could you please put a breakpoint into BlockSupportImpl.reparseRange and paste the full stack trace here? YourKit seems to skip some (inlined?) methods which makes understanding difficult.
Seems it reparses second psi tree:
"AWT-EventQueue-0 14.1.6#IC-141.3057.6, eap:false@2420" prio=6 tid=0x19 nid=NA runnable
java.lang.Thread.State: RUNNABLE
at com.intellij.psi.impl.source.text.BlockSupportImpl.reparseRange(BlockSupportImpl.java:83)
at com.intellij.pom.core.impl.PomModelImpl.reparseFile(PomModelImpl.java:273)
at com.intellij.pom.core.impl.PomModelImpl.reparseParallelTrees(PomModelImpl.java:262)
at com.intellij.pom.core.impl.PomModelImpl.commitTransaction(PomModelImpl.java:244)
at com.intellij.pom.core.impl.PomModelImpl.runTransaction(PomModelImpl.java:194)
- locked <0x4d3a> (a com.intellij.psi.PsiLock)
at com.intellij.psi.impl.source.tree.ChangeUtil.prepareAndRunChangeAction(ChangeUtil.java:165)
at com.intellij.psi.impl.source.tree.CompositeElement.removeChildrenInner(CompositeElement.java:941)
at com.intellij.psi.impl.source.tree.CompositeElement.removeRange(CompositeElement.java:693)
at com.intellij.psi.impl.source.codeStyle.CodeEditUtil.removeChildren(CodeEditUtil.java:172)
at com.intellij.psi.impl.source.codeStyle.CodeEditUtil.removeChild(CodeEditUtil.java:62)
at com.intellij.psi.impl.source.tree.CompositeElement.deleteChildInternal(CompositeElement.java:548)
at com.intellij.psi.impl.source.tree.LeafPsiElement.delete(LeafPsiElement.java:188)
at com.perl5.lang.perl.idea.formatter.operations.PerlFormattingReplace.apply(PerlFormattingReplace.java:79)
at com.perl5.lang.perl.idea.formatter.operations.PerlFormattingScalarDerefCollapse.apply(PerlFormattingScalarDerefCollapse.java:54)
at com.perl5.lang.perl.idea.formatter.PerlPreFormatter$1.runInner(PerlPreFormatter.java:129)
at com.intellij.pom.impl.PomTransactionBase.run(PomTransactionBase.java:44)
at com.intellij.pom.core.impl.PomModelImpl.runTransaction(PomModelImpl.java:150)
at com.perl5.lang.perl.idea.formatter.PerlPreFormatter.process(PerlPreFormatter.java:136)
at com.perl5.lang.perl.idea.formatter.PerlPreFormatProcessor.process(PerlPreFormatProcessor.java:47)
at com.intellij.psi.impl.source.codeStyle.CodeFormatterFacade.preprocess(CodeFormatterFacade.java:329)
at com.intellij.psi.impl.source.codeStyle.CodeFormatterFacade.processText(CodeFormatterFacade.java:196)
at com.intellij.psi.impl.source.codeStyle.CodeStyleManagerImpl.reformatText(CodeStyleManagerImpl.java:224)
at com.intellij.psi.impl.source.codeStyle.CodeStyleManagerImpl.reformatText(CodeStyleManagerImpl.java:164)
at com.intellij.codeInsight.actions.ReformatCodeProcessor$1.call(ReformatCodeProcessor.java:128)
at com.intellij.codeInsight.actions.ReformatCodeProcessor$1.call(ReformatCodeProcessor.java:113)
at java.util.concurrent.FutureTask.run(FutureTask.java:266)
at com.intellij.codeInsight.actions.AbstractLayoutCodeProcessor$1$1.run(AbstractLayoutCodeProcessor.java:238)
at com.intellij.openapi.application.impl.ApplicationImpl.runWriteAction(ApplicationImpl.java:931)
at com.intellij.codeInsight.actions.AbstractLayoutCodeProcessor$1.call(AbstractLayoutCodeProcessor.java:235)
at com.intellij.codeInsight.actions.AbstractLayoutCodeProcessor$1.call(AbstractLayoutCodeProcessor.java:227)
at java.util.concurrent.FutureTask.run(FutureTask.java:266)
at com.intellij.codeInsight.actions.AbstractLayoutCodeProcessor$3.run(AbstractLayoutCodeProcessor.java:342)
at com.intellij.codeInsight.actions.AbstractLayoutCodeProcessor$8$1$1.run(AbstractLayoutCodeProcessor.java:450)
at com.intellij.openapi.command.impl.CoreCommandProcessor.executeCommand(CoreCommandProcessor.java:124)
at com.intellij.openapi.command.impl.CoreCommandProcessor.executeCommand(CoreCommandProcessor.java:99)
at com.intellij.openapi.command.impl.CoreCommandProcessor.executeCommand(CoreCommandProcessor.java:85)
at com.intellij.codeInsight.actions.AbstractLayoutCodeProcessor$8$1.run(AbstractLayoutCodeProcessor.java:445)
at com.intellij.openapi.application.impl.LaterInvocator$FlushQueue.run(LaterInvocator.java:332)
- locked <0x4d3b> (a java.lang.Object)
at java.awt.event.InvocationEvent.dispatch(InvocationEvent.java:311)
at java.awt.EventQueue.dispatchEventImpl(EventQueue.java:756)
at java.awt.EventQueue.access$500(EventQueue.java:97)
at java.awt.EventQueue$3.run(EventQueue.java:709)
at java.awt.EventQueue$3.run(EventQueue.java:703)
at java.security.AccessController.doPrivileged(AccessController.java:-1)
at java.security.ProtectionDomain$JavaSecurityAccessImpl.doIntersectionPrivilege(ProtectionDomain.java:76)
at java.awt.EventQueue.dispatchEvent(EventQueue.java:726)
at com.intellij.ide.IdeEventQueue.defaultDispatchEvent(IdeEventQueue.java:734)
at com.intellij.ide.IdeEventQueue._dispatchEvent(IdeEventQueue.java:569)
at com.intellij.ide.IdeEventQueue.dispatchEvent(IdeEventQueue.java:382)
at java.awt.EventDispatchThread.pumpOneEventForFilters(EventDispatchThread.java:201)
at java.awt.EventDispatchThread.pumpEventsForFilter(EventDispatchThread.java:116)
at java.awt.EventDispatchThread.pumpEventsForHierarchy(EventDispatchThread.java:105)
at java.awt.EventDispatchThread.pumpEvents(EventDispatchThread.java:101)
at java.awt.EventDispatchThread.pumpEvents(EventDispatchThread.java:93)
at java.awt.EventDispatchThread.run(EventDispatchThread.java:82)
I see. Bad news is that I can't think of a workaround for this issue, only if you make all changes in the document and then call reparse (or temporarily pretend that your file has just one PSI root). Good news is that we can try to correct this in master. More bad news is that such major change is not very likely to be backported into released versions :(
What do you mean by pretending that file has one psi root?
Returning one language from the view provider and one file from its getAllFiles. Not sure it can work without some unexpected consequences.
Well, seems too complicated for me yet. Attempting to mimic single file causes too many side effects (exception). WIll try later.