From 8bc5cfb75f993ae3d9bd4e88c9816f38269cf5d7 Mon Sep 17 00:00:00 2001 From: Sebastian Hartte Date: Sun, 21 Dec 2025 13:21:22 +0100 Subject: [PATCH 1/2] Fix NPE by registering a ExternalAnnotationsManager project service --- .../cli/intellij/IntelliJEnvironmentImpl.java | 10 ++ .../MockExternalAnnotationsManager.java | 91 +++++++++++++++++++ settings.gradle | 1 + sourcetest/build.gradle | 11 +++ 4 files changed, 113 insertions(+) create mode 100644 cli/src/main/java/net/neoforged/jst/cli/intellij/MockExternalAnnotationsManager.java create mode 100644 sourcetest/build.gradle diff --git a/cli/src/main/java/net/neoforged/jst/cli/intellij/IntelliJEnvironmentImpl.java b/cli/src/main/java/net/neoforged/jst/cli/intellij/IntelliJEnvironmentImpl.java index 07742fb..fc218dc 100644 --- a/cli/src/main/java/net/neoforged/jst/cli/intellij/IntelliJEnvironmentImpl.java +++ b/cli/src/main/java/net/neoforged/jst/cli/intellij/IntelliJEnvironmentImpl.java @@ -1,5 +1,6 @@ package net.neoforged.jst.cli.intellij; +import com.intellij.codeInsight.ExternalAnnotationsManager; import com.intellij.core.CoreApplicationEnvironment; import com.intellij.core.JavaCoreApplicationEnvironment; import com.intellij.core.JavaCoreProjectEnvironment; @@ -22,11 +23,16 @@ import com.intellij.pom.java.LanguageLevel; import com.intellij.psi.JavaModuleSystem; import com.intellij.psi.JavaPsiFacade; +import com.intellij.psi.PsiAnnotation; +import com.intellij.psi.PsiClass; +import com.intellij.psi.PsiElement; import com.intellij.psi.PsiElementFinder; import com.intellij.psi.PsiFile; import com.intellij.psi.PsiFileFactory; import com.intellij.psi.PsiManager; +import com.intellij.psi.PsiModifierListOwner; import com.intellij.psi.PsiNameHelper; +import com.intellij.psi.PsiNameValuePair; import com.intellij.psi.augment.PsiAugmentProvider; import com.intellij.psi.impl.JavaClassSupersImpl; import com.intellij.psi.impl.PsiElementFinderImpl; @@ -37,12 +43,15 @@ import com.intellij.psi.util.JavaClassSupers; import net.neoforged.jst.api.IntelliJEnvironment; import net.neoforged.jst.api.Logger; +import org.jetbrains.annotations.NotNull; +import org.jetbrains.annotations.Nullable; import org.jetbrains.annotations.VisibleForTesting; import java.io.IOException; import java.nio.file.Files; import java.nio.file.Path; import java.nio.file.Paths; +import java.util.List; import java.util.Objects; public class IntelliJEnvironmentImpl implements IntelliJEnvironment, AutoCloseable { @@ -153,6 +162,7 @@ public PsiFile parseFileFromMemory(String filename, String fileContent) { */ private void initProjectExtensionsAndServices(MockProject project) { project.registerService(PsiNameHelper.class, PsiNameHelperImpl.class); + project.registerService(ExternalAnnotationsManager.class, new MockExternalAnnotationsManager()); var projectExtensions = project.getExtensionArea(); CoreApplicationEnvironment.registerExtensionPoint(projectExtensions, PsiTreeChangePreprocessor.EP.getName(), PsiTreeChangePreprocessor.class); diff --git a/cli/src/main/java/net/neoforged/jst/cli/intellij/MockExternalAnnotationsManager.java b/cli/src/main/java/net/neoforged/jst/cli/intellij/MockExternalAnnotationsManager.java new file mode 100644 index 0000000..f3a4565 --- /dev/null +++ b/cli/src/main/java/net/neoforged/jst/cli/intellij/MockExternalAnnotationsManager.java @@ -0,0 +1,91 @@ +package net.neoforged.jst.cli.intellij; + +import com.intellij.codeInsight.ExternalAnnotationsManager; +import com.intellij.openapi.vfs.VirtualFile; +import com.intellij.psi.PsiAnnotation; +import com.intellij.psi.PsiClass; +import com.intellij.psi.PsiElement; +import com.intellij.psi.PsiFile; +import com.intellij.psi.PsiModifierListOwner; +import com.intellij.psi.PsiNameValuePair; +import org.jetbrains.annotations.NotNull; +import org.jetbrains.annotations.Nullable; + +import java.util.List; + +public class MockExternalAnnotationsManager extends ExternalAnnotationsManager { + @Override + public boolean hasAnnotationRootsForFile(@NotNull VirtualFile file) { + return false; + } + + @Override + public boolean isExternalAnnotation(@NotNull PsiAnnotation annotation) { + return false; + } + + @Override + public @Nullable PsiAnnotation findExternalAnnotation(@NotNull PsiModifierListOwner listOwner, @NotNull String annotationFQN) { + return null; + } + + @Override + public @NotNull List findExternalAnnotations(@NotNull PsiModifierListOwner listOwner, @NotNull String annotationFQN) { + return List.of(); + } + + @Override + public boolean isExternalAnnotationWritable(@NotNull PsiModifierListOwner listOwner, @NotNull String annotationFQN) { + return false; + } + + @Override + public @NotNull PsiAnnotation @NotNull [] findExternalAnnotations(@NotNull PsiModifierListOwner listOwner) { + return new PsiAnnotation[0]; + } + + @Override + public @Nullable List findDefaultConstructorExternalAnnotations(@NotNull PsiClass aClass) { + return List.of(); + } + + @Override + public @Nullable List findDefaultConstructorExternalAnnotations(@NotNull PsiClass aClass, @NotNull String annotationFQN) { + return List.of(); + } + + @Override + public void annotateExternally(@NotNull PsiModifierListOwner listOwner, @NotNull String annotationFQName, @NotNull PsiFile fromFile, PsiNameValuePair @Nullable [] value) throws CanceledConfigurationException { + + } + + @Override + public boolean deannotate(@NotNull PsiModifierListOwner listOwner, @NotNull String annotationFQN) { + return false; + } + + @Override + public boolean editExternalAnnotation(@NotNull PsiModifierListOwner listOwner, @NotNull String annotationFQN, PsiNameValuePair @Nullable [] value) { + return false; + } + + @Override + public @NotNull AnnotationPlace chooseAnnotationsPlaceNoUi(@NotNull PsiElement element) { + return AnnotationPlace.NOWHERE; + } + + @Override + public @NotNull AnnotationPlace chooseAnnotationsPlace(@NotNull PsiElement element) { + return AnnotationPlace.NOWHERE; + } + + @Override + public @Nullable List findExternalAnnotationsFiles(@NotNull PsiModifierListOwner listOwner) { + return List.of(); + } + + @Override + public boolean hasConfiguredAnnotationRoot(@NotNull PsiModifierListOwner owner) { + return false; + } +} diff --git a/settings.gradle b/settings.gradle index 8c5fa61..a773252 100644 --- a/settings.gradle +++ b/settings.gradle @@ -42,3 +42,4 @@ include 'tests' include 'accesstransformers' include 'interfaceinjection' include 'unpick' +include 'sourcetest' \ No newline at end of file diff --git a/sourcetest/build.gradle b/sourcetest/build.gradle new file mode 100644 index 0000000..5456ed1 --- /dev/null +++ b/sourcetest/build.gradle @@ -0,0 +1,11 @@ +/** + * This project only serves to run the application with all plugins from IntelliJ + * while being able to step into original sources. + */ +dependencies { + implementation(project(':cli')) + implementation(project(':accesstransformers')) + implementation(project(':interfaceinjection')) + implementation(project(':parchment')) + implementation(project(':unpick')) +} From 42a0bb2b8ae87710c802db61cb3bdc8c1bf09e74 Mon Sep 17 00:00:00 2001 From: Sebastian Hartte Date: Tue, 30 Dec 2025 15:14:09 +0100 Subject: [PATCH 2/2] Optimize imports. --- api/src/main/java/net/neoforged/jst/api/FileSink.java | 2 -- api/src/main/java/net/neoforged/jst/api/PsiHelper.java | 1 - api/src/main/java/net/neoforged/jst/api/Replacement.java | 1 - api/src/main/java/net/neoforged/jst/api/Replacements.java | 1 - .../jst/cli/intellij/IntelliJEnvironmentImpl.java | 8 -------- .../java/net/neoforged/jst/cli/io/SingleFileSink.java | 1 - .../test/java/net/neoforged/jst/cli/ImportHelperTest.java | 3 --- .../java/net/neoforged/jst/parchment/JavadocHelper.java | 1 - .../parchment/namesanddocs/NameAndDocSourceLoader.java | 1 - 9 files changed, 19 deletions(-) diff --git a/api/src/main/java/net/neoforged/jst/api/FileSink.java b/api/src/main/java/net/neoforged/jst/api/FileSink.java index 3f5cd1b..005e151 100644 --- a/api/src/main/java/net/neoforged/jst/api/FileSink.java +++ b/api/src/main/java/net/neoforged/jst/api/FileSink.java @@ -1,8 +1,6 @@ package net.neoforged.jst.api; -import java.io.ByteArrayInputStream; import java.io.IOException; -import java.io.InputStream; import java.nio.file.attribute.FileTime; public interface FileSink extends AutoCloseable { diff --git a/api/src/main/java/net/neoforged/jst/api/PsiHelper.java b/api/src/main/java/net/neoforged/jst/api/PsiHelper.java index d60a5eb..95e917e 100644 --- a/api/src/main/java/net/neoforged/jst/api/PsiHelper.java +++ b/api/src/main/java/net/neoforged/jst/api/PsiHelper.java @@ -4,7 +4,6 @@ import com.intellij.psi.JavaPsiFacade; import com.intellij.psi.PsiClass; import com.intellij.psi.PsiElement; -import com.intellij.psi.PsiExpression; import com.intellij.psi.PsiMethod; import com.intellij.psi.PsiModifier; import com.intellij.psi.PsiParameter; diff --git a/api/src/main/java/net/neoforged/jst/api/Replacement.java b/api/src/main/java/net/neoforged/jst/api/Replacement.java index 8145b70..b5719d8 100644 --- a/api/src/main/java/net/neoforged/jst/api/Replacement.java +++ b/api/src/main/java/net/neoforged/jst/api/Replacement.java @@ -1,7 +1,6 @@ package net.neoforged.jst.api; import com.intellij.openapi.util.TextRange; -import com.intellij.psi.PsiElement; import java.util.Comparator; diff --git a/api/src/main/java/net/neoforged/jst/api/Replacements.java b/api/src/main/java/net/neoforged/jst/api/Replacements.java index 645e48b..72ac30b 100644 --- a/api/src/main/java/net/neoforged/jst/api/Replacements.java +++ b/api/src/main/java/net/neoforged/jst/api/Replacements.java @@ -4,7 +4,6 @@ import com.intellij.psi.PsiElement; import java.util.ArrayList; -import java.util.Collections; import java.util.List; public final class Replacements { diff --git a/cli/src/main/java/net/neoforged/jst/cli/intellij/IntelliJEnvironmentImpl.java b/cli/src/main/java/net/neoforged/jst/cli/intellij/IntelliJEnvironmentImpl.java index fc218dc..4a53cb8 100644 --- a/cli/src/main/java/net/neoforged/jst/cli/intellij/IntelliJEnvironmentImpl.java +++ b/cli/src/main/java/net/neoforged/jst/cli/intellij/IntelliJEnvironmentImpl.java @@ -23,16 +23,11 @@ import com.intellij.pom.java.LanguageLevel; import com.intellij.psi.JavaModuleSystem; import com.intellij.psi.JavaPsiFacade; -import com.intellij.psi.PsiAnnotation; -import com.intellij.psi.PsiClass; -import com.intellij.psi.PsiElement; import com.intellij.psi.PsiElementFinder; import com.intellij.psi.PsiFile; import com.intellij.psi.PsiFileFactory; import com.intellij.psi.PsiManager; -import com.intellij.psi.PsiModifierListOwner; import com.intellij.psi.PsiNameHelper; -import com.intellij.psi.PsiNameValuePair; import com.intellij.psi.augment.PsiAugmentProvider; import com.intellij.psi.impl.JavaClassSupersImpl; import com.intellij.psi.impl.PsiElementFinderImpl; @@ -43,15 +38,12 @@ import com.intellij.psi.util.JavaClassSupers; import net.neoforged.jst.api.IntelliJEnvironment; import net.neoforged.jst.api.Logger; -import org.jetbrains.annotations.NotNull; -import org.jetbrains.annotations.Nullable; import org.jetbrains.annotations.VisibleForTesting; import java.io.IOException; import java.nio.file.Files; import java.nio.file.Path; import java.nio.file.Paths; -import java.util.List; import java.util.Objects; public class IntelliJEnvironmentImpl implements IntelliJEnvironment, AutoCloseable { diff --git a/cli/src/main/java/net/neoforged/jst/cli/io/SingleFileSink.java b/cli/src/main/java/net/neoforged/jst/cli/io/SingleFileSink.java index b08305b..a601894 100644 --- a/cli/src/main/java/net/neoforged/jst/cli/io/SingleFileSink.java +++ b/cli/src/main/java/net/neoforged/jst/cli/io/SingleFileSink.java @@ -1,7 +1,6 @@ package net.neoforged.jst.cli.io; import net.neoforged.jst.api.FileSink; -import net.neoforged.jst.api.SourceTransformer; import java.io.IOException; import java.nio.file.Files; diff --git a/cli/src/test/java/net/neoforged/jst/cli/ImportHelperTest.java b/cli/src/test/java/net/neoforged/jst/cli/ImportHelperTest.java index 4f28026..70f6384 100644 --- a/cli/src/test/java/net/neoforged/jst/cli/ImportHelperTest.java +++ b/cli/src/test/java/net/neoforged/jst/cli/ImportHelperTest.java @@ -1,10 +1,7 @@ package net.neoforged.jst.cli; -import com.intellij.openapi.vfs.VirtualFile; -import com.intellij.psi.PsiClass; import com.intellij.psi.PsiElement; import com.intellij.psi.PsiJavaFile; -import com.intellij.psi.PsiMethod; import com.intellij.psi.util.PsiTreeUtil; import net.neoforged.jst.api.ImportHelper; import net.neoforged.jst.api.Logger; diff --git a/parchment/src/main/java/net/neoforged/jst/parchment/JavadocHelper.java b/parchment/src/main/java/net/neoforged/jst/parchment/JavadocHelper.java index 94f4427..75a330c 100644 --- a/parchment/src/main/java/net/neoforged/jst/parchment/JavadocHelper.java +++ b/parchment/src/main/java/net/neoforged/jst/parchment/JavadocHelper.java @@ -8,7 +8,6 @@ import com.intellij.psi.javadoc.PsiDocComment; import com.intellij.psi.javadoc.PsiDocToken; import net.neoforged.jst.api.PsiHelper; -import net.neoforged.jst.api.Replacement; import net.neoforged.jst.api.Replacements; import org.jetbrains.annotations.Nullable; diff --git a/parchment/src/main/java/net/neoforged/jst/parchment/namesanddocs/NameAndDocSourceLoader.java b/parchment/src/main/java/net/neoforged/jst/parchment/namesanddocs/NameAndDocSourceLoader.java index fd74038..2e462c2 100644 --- a/parchment/src/main/java/net/neoforged/jst/parchment/namesanddocs/NameAndDocSourceLoader.java +++ b/parchment/src/main/java/net/neoforged/jst/parchment/namesanddocs/NameAndDocSourceLoader.java @@ -2,7 +2,6 @@ import net.neoforged.jst.parchment.namesanddocs.srgutils.MappingFileDatabase; import net.neoforged.jst.parchment.namesanddocs.parchment.ParchmentDatabase; -import net.neoforged.srgutils.INamedMappingFile; import org.jetbrains.annotations.Nullable; import java.io.IOException;