From 98942f9977ffbef3eab3c0fdb26a8786cddf57eb Mon Sep 17 00:00:00 2001 From: Alexey Kudravtsev Date: Fri, 1 Aug 2025 16:27:07 +0200 Subject: [PATCH] optimization: do not (re)compute the whole file text on each PSI change - will lead to quadratic nightmare in case of many small changes (part of IJPL-199461 Recursive elements processing causes SOE) GitOrigin-RevId: 183d62bf30680c6ce02f13abda335729f8d5741f --- .../impl/PsiModificationPerformanceTest.java | 24 +++++++++++++++++++ 1 file changed, 24 insertions(+) create mode 100644 java/java-tests/testSrc/com/intellij/psi/impl/PsiModificationPerformanceTest.java diff --git a/java/java-tests/testSrc/com/intellij/psi/impl/PsiModificationPerformanceTest.java b/java/java-tests/testSrc/com/intellij/psi/impl/PsiModificationPerformanceTest.java new file mode 100644 index 000000000000..b110229c5f93 --- /dev/null +++ b/java/java-tests/testSrc/com/intellij/psi/impl/PsiModificationPerformanceTest.java @@ -0,0 +1,24 @@ +// Copyright 2000-2025 JetBrains s.r.o. and contributors. Use of this source code is governed by the Apache 2.0 license. +package com.intellij.psi.impl; + +import com.intellij.psi.PsiClass; +import com.intellij.psi.PsiElementFactory; +import com.intellij.psi.PsiField; +import com.intellij.testFramework.LightJavaCodeInsightTestCase; + +public class PsiModificationPerformanceTest extends LightJavaCodeInsightTestCase { + public void testManySmallPSIChangesDoNotCauseQuadraticRecomputationsOfWholeFileText() { + int N = 100_000; + String text = " int field;\n".repeat(N); + + PsiClass aClass = PsiElementFactory.getInstance(getProject()).createClassFromText(text, null); + assertFalse(aClass.isPhysical()); + PsiField firstField = aClass.getFields()[0]; + // would pass only if each PSI change does not cause recomputation of the whole file text in com.intellij.psi.impl.source.PsiJavaFileBaseImpl.getLanguageLevelInner + for (int i = 0; i < N; i++) { + firstField.setName("f" + i); + } + assertFalse(aClass.isPhysical()); + assertEquals(N, aClass.getFields().length); + } +}