Fix getMirror for kotlin decompiled file

Possibly fixed EA142049
This commit is contained in:
Igor Yakovlev
2020-02-04 17:13:19 +03:00
parent ab32f2efac
commit 3ec671d727
@@ -16,17 +16,27 @@
package org.jetbrains.kotlin.asJava.elements package org.jetbrains.kotlin.asJava.elements
import com.intellij.lang.java.JavaLanguage
import com.intellij.openapi.fileEditor.FileDocumentManager
import com.intellij.openapi.vfs.VirtualFile import com.intellij.openapi.vfs.VirtualFile
import com.intellij.pom.java.LanguageLevel import com.intellij.pom.java.LanguageLevel
import com.intellij.psi.PsiElement import com.intellij.psi.PsiElement
import com.intellij.psi.PsiElementVisitor import com.intellij.psi.PsiElementVisitor
import com.intellij.psi.PsiFileFactory
import com.intellij.psi.impl.compiled.ClsFileImpl import com.intellij.psi.impl.compiled.ClsFileImpl
import com.intellij.psi.impl.source.PsiFileImpl
import com.intellij.psi.impl.source.SourceTreeToPsiMap
import com.intellij.psi.impl.source.tree.TreeElement
import com.intellij.psi.stubs.PsiClassHolderFileStub import com.intellij.psi.stubs.PsiClassHolderFileStub
import com.intellij.psi.util.PsiUtil
import com.intellij.reference.SoftReference
import com.intellij.util.AstLoadingFilter
import org.jetbrains.kotlin.asJava.classes.KtLightClass import org.jetbrains.kotlin.asJava.classes.KtLightClass
import org.jetbrains.kotlin.asJava.classes.KtLightClassForFacade import org.jetbrains.kotlin.asJava.classes.KtLightClassForFacade
import org.jetbrains.kotlin.asJava.classes.KtLightClassForSourceDeclaration import org.jetbrains.kotlin.asJava.classes.KtLightClassForSourceDeclaration
import org.jetbrains.kotlin.name.FqName import org.jetbrains.kotlin.name.FqName
import org.jetbrains.kotlin.psi.KtFile import org.jetbrains.kotlin.psi.KtFile
import java.lang.ref.Reference
open class FakeFileForLightClass( open class FakeFileForLightClass(
val ktFile: KtFile, val ktFile: KtFile,
@@ -51,6 +61,37 @@ open class FakeFileForLightClass(
// TODO: More complex traversal logic may be implemented when necessary // TODO: More complex traversal logic may be implemented when necessary
} }
@Volatile
private var myMirrorFileElement: Reference<TreeElement>? = null
private val myMirrorLock: Any = Any()
override fun getMirror(): PsiElement {
SoftReference.dereference(myMirrorFileElement)?.let { return it.psi }
val mirrorElement = synchronized(myMirrorLock) {
SoftReference.dereference(myMirrorFileElement)?.let { return@synchronized it }
val file = this.virtualFile
AstLoadingFilter.assertTreeLoadingAllowed(file)
val classes: Array<KtLightClass> = this.classes
val fileName = (if (classes.isNotEmpty()) classes[0].name else file.nameWithoutExtension) + ".java"
val document = FileDocumentManager.getInstance().getDocument(file) ?: error(file.url)
val factory = PsiFileFactory.getInstance(this.manager.project)
val mirror = factory.createFileFromText(fileName, JavaLanguage.INSTANCE, document.immutableCharSequence, false, false, true)
mirror.putUserData(PsiUtil.FILE_LANGUAGE_LEVEL_KEY, this.languageLevel)
val mirrorTreeElement = SourceTreeToPsiMap.psiToTreeNotNull(mirror)
if (mirror is PsiFileImpl) {
mirror.originalFile = this
}
mirrorTreeElement.also {
myMirrorFileElement = SoftReference(it)
}
}
return mirrorElement.psi
}
// this should be equal to current compiler target language level // this should be equal to current compiler target language level
override fun getLanguageLevel() = LanguageLevel.JDK_1_6 override fun getLanguageLevel() = LanguageLevel.JDK_1_6