PY-71854 LoadFile(feat): Add ability to specify File Limit based on an extension. Base impl

Some fies can be huge and do not fit in our standard limits like Go, Jupyter

GitOrigin-RevId: d2555a85d202ea76e643124be02f8eebb2543c08
This commit is contained in:
Nikita.Ashihmin
2024-10-04 10:05:29 +04:00
committed by intellij-monorepo-bot
parent 84a398e4d5
commit 123fe277d6
4 changed files with 113 additions and 1 deletions

View File

@@ -0,0 +1,11 @@
// Copyright 2000-2024 JetBrains s.r.o. and contributors. Use of this source code is governed by the Apache 2.0 license.
package com.intellij.openapi.vfs.limits
import org.jetbrains.annotations.ApiStatus
@ApiStatus.Internal
data class ExtensionSizeLimitInfo(
val content: Int? = null,
val intellijSense: Int? = null,
val preview: Int? = null,
)

View File

@@ -0,0 +1,94 @@
// Copyright 2000-2024 JetBrains s.r.o. and contributors. Use of this source code is governed by the Apache 2.0 license.
package com.intellij.openapi.vfs.limits
import com.intellij.openapi.application.ApplicationManager
import com.intellij.openapi.diagnostic.thisLogger
import com.intellij.openapi.extensions.ExtensionPointName
import com.intellij.openapi.util.io.FileUtilRt
import com.intellij.openapi.vfs.PersistentFSConstants
import org.jetbrains.annotations.ApiStatus
import java.util.concurrent.atomic.AtomicReference
@Suppress("DEPRECATION")
@ApiStatus.Internal
interface FileSizeLimit {
val acceptableExtensions: String
fun getLimits(): ExtensionSizeLimitInfo
companion object {
private val EP: ExtensionPointName<FileSizeLimit> = ExtensionPointName("com.intellij.fileEditor.fileSizeChecker")
private val limitsByExtension: AtomicReference<Map<String, ExtensionSizeLimitInfo>?> = AtomicReference(null)
@JvmStatic
@ApiStatus.Internal
fun getFileLengthToCacheThreshold(): Int = FileUtilRt.LARGE_FOR_CONTENT_LOADING
private fun getLimitsByExtension(): Map<String, ExtensionSizeLimitInfo> {
return limitsByExtension.get() ?: limitsByExtension.updateAndGet { getLimits() }!!
}
init {
val extensionPoint = ApplicationManager.getApplication().extensionArea.getExtensionPointIfRegistered<FileSizeLimit>(EP.name)
extensionPoint?.addChangeListener({ limitsByExtension.set(null) }, null)
}
/**
* Fingerprint of the current state (to contribute to indexing fingerprint)
*/
fun getFingerprint(): Int {
return getLimitsByExtension().hashCode()
}
@JvmStatic
fun isTooLarge(fileSize: Long, extension: String? = ""): Boolean {
val fileContentLoadLimit = getContentLoadLimit(extension)
return fileSize > fileContentLoadLimit
}
@JvmStatic
fun getContentLoadLimit(extension: String?): Int {
@Suppress("DEPRECATION")
val limit = findApplicable(extension ?: "")?.content ?: FileUtilRt.LARGE_FOR_CONTENT_LOADING
return limit
}
@JvmStatic
fun getContentLoadLimit(): Int = getContentLoadLimit(null)
@JvmStatic
fun getIntellisenseLimit(): Int = getIntellisenseLimit(null)
@JvmStatic
fun getIntellisenseLimit(extension: String?): Int {
@Suppress("DEPRECATION")
val limit = findApplicable(extension ?: "")?.intellijSense ?: PersistentFSConstants.getMaxIntellisenseFileSize()
return limit
}
@JvmStatic
fun getPreviewLimit(extension: String? = ""): Int {
@Suppress("DEPRECATION")
val limit = findApplicable(extension?:"")?.preview ?: FileUtilRt.LARGE_FILE_PREVIEW_SIZE
return limit
}
private fun getLimits(): Map<String, ExtensionSizeLimitInfo> {
val extensions = EP.extensionsIfPointIsRegistered
val grouped = extensions.groupBy { it.acceptableExtensions }
grouped.forEach { (type, checkers) ->
if (checkers.size > 1) {
thisLogger().warn("For file type $type several limits from extensions: ${checkers.joinToString { it::class.java.name }}. " +
"IDE can work incorrectly")
}
}
val newLimits = grouped.map { it.key to it.value.first().getLimits() }.toMap()
return newLimits
}
private fun findApplicable(extension: String): ExtensionSizeLimitInfo? = getLimitsByExtension()[extension]
}
}

View File

@@ -3,15 +3,19 @@
<extensionPoint name="virtualFileSystem" beanClass="com.intellij.openapi.vfs.impl.VirtualFileManagerImpl$VirtualFileSystemBean" dynamic="true">
<with attribute="implementationClass" implements="com.intellij.openapi.vfs.VirtualFileSystem"/>
</extensionPoint>
<extensionPoint name="fileEditor.textPresentationTransformer" beanClass="com.intellij.openapi.fileTypes.FileTypeExtensionPoint" dynamic="true">
<with attribute="implementationClass" implements="com.intellij.openapi.vfs.transformer.TextPresentationTransformer"/>
</extensionPoint>
<extensionPoint name="psi.treeChangeListener"
interface="com.intellij.psi.PsiTreeChangeListener"
area="IDEA_PROJECT"
dynamic="true"/>
<extensionPoint name="fileEditor.fileSizeChecker"
interface="com.intellij.openapi.vfs.limits.FileSizeLimit"
dynamic="true"/>
<extensionPoint name="psi.treeChangePreprocessor"
interface="com.intellij.psi.impl.PsiTreeChangePreprocessor"
area="IDEA_PROJECT"

View File

@@ -11,6 +11,7 @@ import com.intellij.openapi.application.PathManager
import com.intellij.openapi.application.impl.ApplicationInfoImpl
import com.intellij.openapi.diagnostic.Logger
import com.intellij.openapi.progress.ProgressManager
import com.intellij.openapi.vfs.limits.FileSizeLimit
import org.jetbrains.annotations.ApiStatus.Internal
import java.nio.file.Files
import java.nio.file.LinkOption
@@ -73,6 +74,8 @@ private fun computeIdeFingerprint(debugHelperToken: Int): IdeFingerprint {
hasher.putInt(debugHelperToken)
hasher.putInt(FileSizeLimit.getFingerprint())
val fingerprint = IdeFingerprint(hasher.asLong)
val durationMs = System.currentTimeMillis() - startTime