From 28b199c54957bb10d203bb5d7a0e3ed82603f5e8 Mon Sep 17 00:00:00 2001 From: Christopher Ng Date: Wed, 6 Sep 2023 11:23:56 -0700 Subject: [PATCH] Fix `java.lang.RuntimeException: Document is locked by write PSI operations` errors Also update to `google-java-format` 1.17.0 Fixes #960 COPYBARA_INTEGRATE_REVIEW=https://github.com/google/google-java-format/pull/960 from facboy:master e0925a2e7d7c94e84a1c1fd6bb95ff9ca1b66c79 PiperOrigin-RevId: 563163224 --- idea_plugin/build.gradle.kts | 18 ++++++------ .../GoogleJavaFormatImportOptimizer.java | 28 ++++++++++++++++--- 2 files changed, 33 insertions(+), 13 deletions(-) diff --git a/idea_plugin/build.gradle.kts b/idea_plugin/build.gradle.kts index 474c24d79..0aec5a7b6 100644 --- a/idea_plugin/build.gradle.kts +++ b/idea_plugin/build.gradle.kts @@ -14,7 +14,7 @@ * limitations under the License. */ -plugins { id("org.jetbrains.intellij") version "1.13.3" } +plugins { id("org.jetbrains.intellij") version "1.15.0" } apply(plugin = "org.jetbrains.intellij") @@ -22,7 +22,7 @@ apply(plugin = "java") repositories { mavenCentral() } -val googleJavaFormatVersion = "1.16.0" +val googleJavaFormatVersion = "1.17.0" java { sourceCompatibility = JavaVersion.VERSION_11 @@ -37,7 +37,7 @@ intellij { tasks { patchPluginXml { - version.set("${googleJavaFormatVersion}.2") + version.set("${googleJavaFormatVersion}.0") sinceBuild.set("213") untilBuild.set("") } @@ -49,12 +49,12 @@ tasks { withType().configureEach { jvmArgs( - "--add-exports jdk.compiler/com.sun.tools.javac.api=ALL-UNNAMED", - "--add-exports jdk.compiler/com.sun.tools.javac.code=ALL-UNNAMED", - "--add-exports jdk.compiler/com.sun.tools.javac.file=ALL-UNNAMED", - "--add-exports jdk.compiler/com.sun.tools.javac.parser=ALL-UNNAMED", - "--add-exports jdk.compiler/com.sun.tools.javac.tree=ALL-UNNAMED", - "--add-exports jdk.compiler/com.sun.tools.javac.util=ALL-UNNAMED", + "--add-exports", "jdk.compiler/com.sun.tools.javac.api=ALL-UNNAMED", + "--add-exports", "jdk.compiler/com.sun.tools.javac.code=ALL-UNNAMED", + "--add-exports", "jdk.compiler/com.sun.tools.javac.file=ALL-UNNAMED", + "--add-exports", "jdk.compiler/com.sun.tools.javac.parser=ALL-UNNAMED", + "--add-exports", "jdk.compiler/com.sun.tools.javac.tree=ALL-UNNAMED", + "--add-exports", "jdk.compiler/com.sun.tools.javac.util=ALL-UNNAMED", ) } } diff --git a/idea_plugin/src/main/java/com/google/googlejavaformat/intellij/GoogleJavaFormatImportOptimizer.java b/idea_plugin/src/main/java/com/google/googlejavaformat/intellij/GoogleJavaFormatImportOptimizer.java index 498c88526..bad03457a 100644 --- a/idea_plugin/src/main/java/com/google/googlejavaformat/intellij/GoogleJavaFormatImportOptimizer.java +++ b/idea_plugin/src/main/java/com/google/googlejavaformat/intellij/GoogleJavaFormatImportOptimizer.java @@ -55,16 +55,36 @@ public boolean supports(@NotNull PsiFile file) { JavaFormatterOptions.Style style = GoogleJavaFormatSettings.getInstance(project).getStyle(); + final String origText = document.getText(); String text; try { - text = - ImportOrderer.reorderImports( - RemoveUnusedImports.removeUnusedImports(document.getText()), style); + text = ImportOrderer.reorderImports(RemoveUnusedImports.removeUnusedImports(origText), style); } catch (FormatterException e) { Notifications.displayParsingErrorNotification(project, file.getName()); return Runnables.doNothing(); } - return () -> document.setText(text); + /* pointless to change document text if it hasn't changed, plus this can interfere with + e.g. GoogleJavaFormattingService's output, i.e. it can overwrite the results from the main + formatter. */ + if (text.equals(origText)) { + return Runnables.doNothing(); + } + + return () -> { + if (documentManager.isDocumentBlockedByPsi(document)) { + documentManager.doPostponedOperationsAndUnblockDocument(document); + } + + /* similarly to above, don't overwrite new document text if it has changed - we use + getCharsSequence() as we should have `writeAction()` (which I think means effectively a + write-lock) and it saves calling getText(), which apparently is expensive. */ + CharSequence newText = document.getCharsSequence(); + if (CharSequence.compare(origText, newText) != 0) { + return; + } + + document.setText(text); + }; } }