LightClassUtil: files can no longer "belong to builtIns"

This commit is contained in:
Pavel V. Talanov
2015-12-15 14:54:00 +03:00
parent bd9221beaa
commit 8d5d1b7dcc
6 changed files with 11 additions and 110 deletions
@@ -390,10 +390,6 @@ public open class KtLightClassForExplicitDeclaration(
public fun create(classOrObject: KtClassOrObject): KtLightClassForExplicitDeclaration? {
if (LightClassUtil.belongsToKotlinBuiltIns(classOrObject.getContainingKtFile())) {
return null
}
val fqName = predictFqName(classOrObject) ?: return null
if (classOrObject is KtObjectDeclaration && classOrObject.isObjectLiteral()) {
@@ -194,11 +194,7 @@ public class KtLightClassForFacade private constructor(
facadeClassFqName: FqName,
searchScope: GlobalSearchScope,
files: Collection<KtFile>
): KtLightClassForFacade? {
if (files.any { LightClassUtil.belongsToKotlinBuiltIns(it) }) {
return null
}
): KtLightClassForFacade {
assert(files.isNotEmpty()) { "No files for facade $facadeClassFqName" }
val lightClassDataCache = FacadeStubCache.getInstance(manager.project).get(facadeClassFqName, searchScope)
@@ -73,8 +73,6 @@ abstract class LightClassDataProvider<T : WithFileStubAndExtraDiagnostics>(
val packageFqName = packageFqName
val files = files
checkForBuiltIns(packageFqName, files)
val context = getContext(files)
val javaFileStub = createJavaFileStub(packageFqName, files)
@@ -154,20 +152,10 @@ abstract class LightClassDataProvider<T : WithFileStubAndExtraDiagnostics>(
return files.firstOrNull()?.virtualFile.sure { "No virtual file for " + files.iterator().next() }
}
private fun checkForBuiltIns(fqName: FqName, files: Collection<KtFile>) {
for (file in files) {
if (LightClassUtil.belongsToKotlinBuiltIns(file)) {
// We may not fail later due to some luck, but generating JetLightClasses for built-ins is a bad idea anyways
// If it fails later, there will be an exception logged
logErrorWithOSInfo(null, fqName, file.virtualFile)
}
}
}
private fun logErrorWithOSInfo(cause: Throwable?, fqName: FqName, virtualFile: VirtualFile?) {
val path = if (virtualFile == null) "<null>" else virtualFile.path
LOG.error(
"Could not generate LightClass for $fqName declared in $path\nbuilt-ins dir URL is ${LightClassUtil.builtInsDirUrl}\n" +
"Could not generate LightClass for $fqName declared in $path\n" +
"System: ${SystemInfo.OS_NAME} ${SystemInfo.OS_VERSION} Java Runtime: ${SystemInfo.JAVA_RUNTIME_VERSION}",
cause
)
@@ -16,98 +16,22 @@
package org.jetbrains.kotlin.asJava
import com.intellij.openapi.application.ApplicationManager
import com.intellij.openapi.diagnostic.Logger
import com.intellij.openapi.progress.ProcessCanceledException
import com.intellij.openapi.util.Comparing
import com.intellij.openapi.util.io.FileUtil
import com.intellij.openapi.vfs.StandardFileSystems
import com.intellij.psi.*
import com.intellij.psi.impl.java.stubs.PsiClassStub
import com.intellij.psi.search.GlobalSearchScope
import com.intellij.psi.stubs.PsiFileStub
import com.intellij.psi.stubs.StubElement
import com.intellij.psi.util.PsiTreeUtil
import com.intellij.util.PathUtil
import com.intellij.util.SmartList
import org.jetbrains.kotlin.builtins.KotlinBuiltIns
import org.jetbrains.kotlin.fileClasses.javaFileFacadeFqName
import org.jetbrains.kotlin.load.java.JvmAbi
import org.jetbrains.kotlin.name.FqName
import org.jetbrains.kotlin.psi.*
import org.jetbrains.kotlin.psi.psiUtil.getNonStrictParentOfType
import org.jetbrains.kotlin.utils.KotlinVfsUtil
import org.jetbrains.kotlin.utils.rethrow
import java.io.File
import java.net.MalformedURLException
import java.net.URL
public object LightClassUtil {
private val LOG = Logger.getInstance(LightClassUtil::class.java)
public val BUILT_INS_SRC_DIR: File = File("core/builtins/native", KotlinBuiltIns.BUILT_INS_PACKAGE_NAME.asString())
public val builtInsDirUrl: URL by lazy { computeBuiltInsDir() }
/**
* Checks whether the given file is loaded from the location where Kotlin's built-in classes are defined.
* As of today, this is core/builtins/native/kotlin directory and files such as Any.kt, Nothing.kt etc.
* Used to skip JetLightClass creation for built-ins, because built-in classes have no Java counterparts
*/
public fun belongsToKotlinBuiltIns(file: KtFile): Boolean {
val virtualFile = file.virtualFile
if (virtualFile != null) {
val parent = virtualFile.parent
if (parent != null) {
try {
val jetVfsPathUrl = KotlinVfsUtil.convertFromUrl(builtInsDirUrl)
val fileDirVfsUrl = parent.url
if (jetVfsPathUrl == fileDirVfsUrl) {
return true
}
}
catch (e: MalformedURLException) {
LOG.error(e)
}
}
}
// We deliberately return false on error: who knows what weird URLs we might come across out there
// it would be a pity if no light classes would be created in such cases
return false
}
private fun computeBuiltInsDir(): URL {
val builtInFilePath = "/" + KotlinBuiltIns.BUILT_INS_PACKAGE_NAME + "/Library.kt"
val url = KotlinBuiltIns::class.java.getResource(builtInFilePath)
if (url == null) {
if (ApplicationManager.getApplication().isUnitTestMode) {
// HACK: Temp code. Get built-in files from the sources when running from test.
try {
return URL(StandardFileSystems.FILE_PROTOCOL, "",
FileUtil.toSystemIndependentName(BUILT_INS_SRC_DIR.absolutePath))
}
catch (e: MalformedURLException) {
throw rethrow(e)
}
}
throw IllegalStateException("Built-ins file wasn't found at url: " + builtInFilePath)
}
try {
return URL(url.protocol, url.host, PathUtil.getParentPath(url.file))
}
catch (e: MalformedURLException) {
throw AssertionError(e)
}
}
fun findClass(fqn: FqName, stub: StubElement<*>): PsiClass? {
if (stub is PsiClassStub<*> && Comparing.equal(fqn.asString(), stub.qualifiedName)) {
@@ -23,7 +23,6 @@ import com.intellij.openapi.project.Project
import com.intellij.psi.PsiElement
import com.intellij.psi.util.PsiTreeUtil
import org.jetbrains.kotlin.analyzer.AnalysisResult
import org.jetbrains.kotlin.asJava.LightClassUtil
import org.jetbrains.kotlin.container.ComponentProvider
import org.jetbrains.kotlin.container.get
import org.jetbrains.kotlin.context.GlobalContext
@@ -153,7 +152,7 @@ private object KotlinResolveDataProvider {
}
val file = analyzableElement.getContainingKtFile()
if (LightClassUtil.belongsToKotlinBuiltIns(file) || file.getModuleInfo() is LibrarySourceInfo) {
if (file.getModuleInfo() is LibrarySourceInfo) {
// Library sources: mark file to skip
file.putUserData(LibrarySourceHacks.SKIP_TOP_LEVEL_MEMBERS, true)
}
@@ -365,16 +365,14 @@ public class SourceNavigationHelper {
@Nullable
public static PsiClass getOriginalPsiClassOrCreateLightClass(@NotNull KtClassOrObject classOrObject) {
if (LightClassUtil.INSTANCE$.belongsToKotlinBuiltIns(classOrObject.getContainingKtFile())) {
FqName fqName = classOrObject.getFqName();
if (fqName != null) {
ClassId javaClassId = JavaToKotlinClassMap.INSTANCE.mapKotlinToJava(fqName.toUnsafe());
if (javaClassId != null) {
return JavaPsiFacade.getInstance(classOrObject.getProject()).findClass(
javaClassId.asSingleFqName().asString(),
GlobalSearchScope.allScope(classOrObject.getProject())
);
}
FqName fqName = classOrObject.getFqName();
if (fqName != null) {
ClassId javaClassId = JavaToKotlinClassMap.INSTANCE.mapKotlinToJava(fqName.toUnsafe());
if (javaClassId != null) {
return JavaPsiFacade.getInstance(classOrObject.getProject()).findClass(
javaClassId.asSingleFqName().asString(),
GlobalSearchScope.allScope(classOrObject.getProject())
);
}
}
return LightClassUtil.INSTANCE$.getPsiClass(classOrObject);