Patch initializing EmptySubstitutor service and fix null references
There's a cycle in service initialization and PsiSubstitutor 'clinit'
This commit is contained in:
+49
-1
@@ -30,6 +30,7 @@ import com.intellij.openapi.fileTypes.PlainTextFileType;
|
||||
import com.intellij.openapi.fileTypes.PlainTextLanguage;
|
||||
import com.intellij.openapi.fileTypes.PlainTextParserDefinition;
|
||||
import com.intellij.openapi.projectRoots.JavaVersionService;
|
||||
import com.intellij.openapi.util.KeyWithDefaultValue;
|
||||
import com.intellij.openapi.vfs.VirtualFileSystem;
|
||||
import com.intellij.psi.*;
|
||||
import com.intellij.psi.augment.PsiAugmentProvider;
|
||||
@@ -52,6 +53,9 @@ import org.jetbrains.annotations.NotNull;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
import org.jetbrains.kotlin.cli.jvm.modules.CoreJrtFileSystem;
|
||||
|
||||
import java.lang.reflect.Field;
|
||||
import java.lang.reflect.Modifier;
|
||||
|
||||
/**
|
||||
* adapted from com.intellij.core.JavaCoreApplicationEnvironment
|
||||
* TODO: initiate removal original from com.intellij.core since it seems that there are no usages left
|
||||
@@ -109,7 +113,14 @@ public class KotlinCoreApplicationEnvironment extends CoreApplicationEnvironment
|
||||
|
||||
myApplication.registerService(PsiPackageImplementationHelper.class, new CorePsiPackageImplementationHelper());
|
||||
|
||||
myApplication.registerService(EmptySubstitutor.class, new EmptySubstitutorImpl());
|
||||
EmptySubstitutorImpl emptySubstitutor = new EmptySubstitutorImpl();
|
||||
myApplication.registerService(EmptySubstitutor.class, emptySubstitutor);
|
||||
|
||||
// Patch null values obtained because of cyclic dependency during initialization
|
||||
updateInterfaceField(PsiSubstitutor.class, "KEY", KeyWithDefaultValue.create("SUBSTITUTOR", emptySubstitutor));
|
||||
updateInterfaceField(PsiSubstitutor.class, "EMPTY", emptySubstitutor);
|
||||
updateInterfaceField(PsiSubstitutor.class, "UNKNOWN", PsiSubstitutor.EMPTY);
|
||||
|
||||
myApplication.registerService(JavaDirectoryService.class, createJavaDirectoryService());
|
||||
myApplication.registerService(JavaVersionService.class, new JavaVersionService());
|
||||
|
||||
@@ -147,4 +158,41 @@ public class KotlinCoreApplicationEnvironment extends CoreApplicationEnvironment
|
||||
protected VirtualFileSystem createJrtFileSystem() {
|
||||
return new CoreJrtFileSystem();
|
||||
}
|
||||
|
||||
private static void updateInterfaceField(Class<?> klass, String name, Object value) {
|
||||
try {
|
||||
Field field = klass.getDeclaredField(name);
|
||||
|
||||
boolean wasAccessible = field.isAccessible();
|
||||
|
||||
try {
|
||||
if (!wasAccessible) {
|
||||
field.setAccessible(true);
|
||||
}
|
||||
|
||||
Field modifiersField = Field.class.getDeclaredField("modifiers");
|
||||
|
||||
int modifiers = field.getModifiers();
|
||||
|
||||
try {
|
||||
modifiersField.setAccessible(true);
|
||||
modifiersField.setInt(field, modifiers & ~Modifier.FINAL);
|
||||
|
||||
field.set(null, value);
|
||||
}
|
||||
finally {
|
||||
modifiersField.setInt(field, modifiers);
|
||||
modifiersField.setAccessible(false);
|
||||
}
|
||||
}
|
||||
finally {
|
||||
if (!wasAccessible) {
|
||||
field.setAccessible(false);
|
||||
}
|
||||
}
|
||||
}
|
||||
catch (NoSuchFieldException | IllegalAccessException e) {
|
||||
throw new IllegalStateException(e);
|
||||
}
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user