PY-70729: Move com.jetbrains.extensions deprecated package to the separate module.

This package is only used by third party plugins. We can't leave it inside another v2 module due to package inconsistency.

See errors like https://youtrack.jetbrains.com/issue/PY-70729/Class-com.jetbrains.python.psi.PyElementType-must-not-be-requested-from-main-classloader-of-Pythonid-plugin#focus=Comments-27-9494155.0-0

So we move it to the separate v2 module which will be removed soon

GitOrigin-RevId: 418ef1a59bb5e63dbc368a936437408c6510cc23
This commit is contained in:
Ilya.Kazakevich
2024-03-18 22:49:18 +01:00
committed by intellij-monorepo-bot
parent 8b3a0122c2
commit d7c00ac3da
12 changed files with 116 additions and 246 deletions

View File

@@ -0,0 +1,19 @@
<?xml version="1.0" encoding="UTF-8"?>
<module type="JAVA_MODULE" version="4">
<component name="NewModuleRootManager" inherit-compiler-output="true">
<exclude-output />
<content url="file://$MODULE_DIR$">
<sourceFolder url="file://$MODULE_DIR$/src" isTestSource="false" />
</content>
<orderEntry type="inheritedJdk" />
<orderEntry type="sourceFolder" forTests="false" />
<orderEntry type="library" name="jetbrains-annotations" level="project" />
<orderEntry type="module" module-name="intellij.platform.projectModel" />
<orderEntry type="library" name="kotlin-stdlib" level="project" />
<orderEntry type="module" module-name="intellij.python.psi" />
<orderEntry type="module" module-name="intellij.python.psi.impl" />
<orderEntry type="module" module-name="intellij.python.sdk" />
<orderEntry type="module" module-name="intellij.python.community.core.impl" />
<orderEntry type="module" module-name="intellij.platform.indexing" />
</component>
</module>

View File

@@ -0,0 +1,85 @@
// Copyright 2000-2024 JetBrains s.r.o. and contributors. Use of this source code is governed by the Apache 2.0 license.
package com.jetbrains.extensions
import com.intellij.openapi.module.Module
import com.intellij.openapi.project.Project
import com.intellij.openapi.projectRoots.Sdk
import com.intellij.openapi.roots.ModuleRootManager
import com.intellij.openapi.roots.OrderRootType
import com.intellij.openapi.vfs.VirtualFile
import com.intellij.psi.search.GlobalSearchScope
import com.intellij.psi.util.QualifiedName
import com.jetbrains.python.extensions.getSdk
import com.jetbrains.python.psi.resolve.PyQualifiedNameResolveContext
import com.jetbrains.python.psi.resolve.fromModule
import com.jetbrains.python.psi.types.TypeEvalContext
import org.jetbrains.annotations.ApiStatus
import java.util.*
/**
* @deprecated moved to {@link com.jetbrains.python.extensions}
*/
@ApiStatus.ScheduledForRemoval
@Deprecated(message = "Moved to com.jetbrains.python")
interface ContextAnchor {
val sdk: Sdk?
val project: Project
val qualifiedNameResolveContext: PyQualifiedNameResolveContext?
val scope: GlobalSearchScope
fun getRoots(): Array<VirtualFile> {
return sdk?.rootProvider?.getFiles(OrderRootType.CLASSES) ?: emptyArray()
}
}
/**
* @deprecated moved to {@link com.jetbrains.python.extensions}
*/
@ApiStatus.ScheduledForRemoval
@Deprecated(message = "Moved to com.jetbrains.python")
class ModuleBasedContextAnchor(val module: Module) : ContextAnchor {
override val sdk: Sdk? = module.getSdk()
override val project: Project = module.project
override val qualifiedNameResolveContext: PyQualifiedNameResolveContext = fromModule(module)
override val scope: GlobalSearchScope = module.moduleContentScope
override fun getRoots(): Array<VirtualFile> {
val manager = ModuleRootManager.getInstance(module)
return super.getRoots() + manager.contentRoots + manager.sourceRoots
}
}
/**
* @deprecated moved to {@link com.jetbrains.python.extensions}
*/
@ApiStatus.ScheduledForRemoval
@Deprecated(message = "Moved to com.jetbrains.python")
data class QNameResolveContext(
val contextAnchor: ContextAnchor,
/**
* Used for language level etc
*/
val sdk: Sdk? = contextAnchor.sdk,
val evalContext: TypeEvalContext,
/**
* If not provided resolves against roots only. Resolved also against this folder otherwise
*/
val folderToStart: VirtualFile? = null,
/**
* Use index, plain dirs with Py2 and so on. May resolve names unresolvable in other cases, but may return false results.
*/
val allowInaccurateResult: Boolean = false
)
/**
* @deprecated moved to {@link com.jetbrains.python.extensions}
*/
@ApiStatus.ScheduledForRemoval
@Deprecated(message = "Moved to com.jetbrains.python")
fun QualifiedName.getRelativeNameTo(root: QualifiedName): QualifiedName? {
if (Collections.indexOfSubList(components, root.components) == -1) {
return null
}
return subQualifiedName(root.componentCount, componentCount)
}

View File

@@ -0,0 +1,7 @@
<idea-plugin package="com.jetbrains.extensions">
<!--This module will be removed soon, do not use it-->
<dependencies>
<plugin id="com.intellij.modules.lang"/>
<module name="intellij.python.community.impl"/>
</dependencies>
</idea-plugin>

View File

@@ -1,25 +0,0 @@
/*
* Copyright 2000-2016 JetBrains s.r.o.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package com.jetbrains.extensions
import com.intellij.openapi.module.Module
import com.intellij.openapi.projectRoots.Sdk
import com.intellij.openapi.roots.ModuleRootManager
import org.jetbrains.annotations.ApiStatus.ScheduledForRemoval
@Deprecated(message = "Moved to com.jetbrains.python")
@ScheduledForRemoval
fun Module.getSdk(): Sdk? = ModuleRootManager.getInstance(this).sdk

View File

@@ -1,194 +0,0 @@
// Copyright 2000-2024 JetBrains s.r.o. and contributors. Use of this source code is governed by the Apache 2.0 license.
package com.jetbrains.extensions
import com.intellij.openapi.module.Module
import com.intellij.openapi.project.Project
import com.intellij.openapi.projectRoots.Sdk
import com.intellij.openapi.roots.ModuleRootManager
import com.intellij.openapi.roots.OrderRootType
import com.intellij.openapi.roots.ProjectRootManager
import com.intellij.openapi.vfs.VirtualFile
import com.intellij.psi.PsiDirectory
import com.intellij.psi.PsiElement
import com.intellij.psi.PsiManager
import com.intellij.psi.search.GlobalSearchScope
import com.intellij.psi.util.QualifiedName
import com.jetbrains.python.PyNames
import com.jetbrains.python.psi.PyClass
import com.jetbrains.python.psi.PyFile
import com.jetbrains.python.psi.resolve.*
import com.jetbrains.python.psi.stubs.PyModuleNameIndex
import com.jetbrains.python.psi.types.TypeEvalContext
import com.jetbrains.python.sdk.PySdkUtil
import org.jetbrains.annotations.ApiStatus
import java.util.*
/**
* @deprecated moved to {@link com.jetbrains.python.extensions}
*/
@ApiStatus.ScheduledForRemoval
@Deprecated(message = "Moved to com.jetbrains.python")
interface ContextAnchor {
val sdk: Sdk?
val project: Project
val qualifiedNameResolveContext: PyQualifiedNameResolveContext?
val scope: GlobalSearchScope
fun getRoots(): Array<VirtualFile> {
return sdk?.rootProvider?.getFiles(OrderRootType.CLASSES) ?: emptyArray()
}
}
/**
* @deprecated moved to {@link com.jetbrains.python.extensions}
*/
@ApiStatus.ScheduledForRemoval
@Deprecated(message = "Moved to com.jetbrains.python")
class ModuleBasedContextAnchor(val module: Module) : ContextAnchor {
override val sdk: Sdk? = module.getSdk()
override val project: Project = module.project
override val qualifiedNameResolveContext: PyQualifiedNameResolveContext = fromModule(module)
override val scope: GlobalSearchScope = module.moduleContentScope
override fun getRoots(): Array<VirtualFile> {
val manager = ModuleRootManager.getInstance(module)
return super.getRoots() + manager.contentRoots + manager.sourceRoots
}
}
/**
* @deprecated moved to {@link com.jetbrains.python.extensions}
*/
@ApiStatus.ScheduledForRemoval
@Deprecated(message = "Moved to com.jetbrains.python")
data class QNameResolveContext(
val contextAnchor: ContextAnchor,
/**
* Used for language level etc
*/
val sdk: Sdk? = contextAnchor.sdk,
val evalContext: TypeEvalContext,
/**
* If not provided resolves against roots only. Resolved also against this folder otherwise
*/
val folderToStart: VirtualFile? = null,
/**
* Use index, plain dirs with Py2 and so on. May resolve names unresolvable in other cases, but may return false results.
*/
val allowInaccurateResult: Boolean = false
)
/**
* @deprecated moved to {@link com.jetbrains.python.extensions}
*/
@ApiStatus.ScheduledForRemoval
@Deprecated(message = "Moved to com.jetbrains.python")
fun QualifiedName.resolveToElement(context: QNameResolveContext, stopOnFirstFail: Boolean = false): PsiElement? {
return getElementAndResolvableName(context, stopOnFirstFail)?.element
}
/**
* @deprecated moved to {@link com.jetbrains.python.extensions}
*/
@ApiStatus.ScheduledForRemoval
@Deprecated(message = "Moved to com.jetbrains.python")
fun QualifiedName.getRelativeNameTo(root: QualifiedName): QualifiedName? {
if (Collections.indexOfSubList(components, root.components) == -1) {
return null
}
return subQualifiedName(root.componentCount, componentCount)
}
/**
* @deprecated moved to {@link com.jetbrains.python.extensions}
*/
@ApiStatus.ScheduledForRemoval
@Deprecated(message = "Moved to com.jetbrains.python")
class ProjectSdkContextAnchor(override val project: Project, override val sdk: Sdk?) : com.jetbrains.python.extensions.ContextAnchor {
override val qualifiedNameResolveContext: PyQualifiedNameResolveContext? = sdk?.let { fromSdk(project, it) }
override val scope: GlobalSearchScope = GlobalSearchScope.projectScope(project) //TODO: Check if project scope includes SDK
override fun getRoots(): Array<VirtualFile> {
val manager = ProjectRootManager.getInstance(project)
return super.getRoots() + manager.contentRoots + manager.contentSourceRoots
}
}
/**
* @deprecated moved to {@link com.jetbrains.python.extensions}
*/
@ApiStatus.ScheduledForRemoval
@Deprecated(message = "Moved to com.jetbrains.python")
data class NameAndElement(val name: QualifiedName, val element: PsiElement)
/**
* @deprecated moved to {@link com.jetbrains.python.extensions}
*/
@ApiStatus.ScheduledForRemoval
@Deprecated(message = "Moved to com.jetbrains.python")
fun QualifiedName.getElementAndResolvableName(context: QNameResolveContext, stopOnFirstFail: Boolean = false): NameAndElement? {
var currentName = QualifiedName.fromComponents(this.components)
var element: PsiElement? = null
var lastElement: String? = null
var psiDirectory: PsiDirectory? = null
var resolveContext = context.contextAnchor.qualifiedNameResolveContext?.copyWithMembers() ?: return null
if (PySdkUtil.getLanguageLevelForSdk(context.sdk).isPy3K || context.allowInaccurateResult) {
resolveContext = resolveContext.copyWithPlainDirectories()
}
if (context.folderToStart != null) {
psiDirectory = PsiManager.getInstance(context.contextAnchor.project).findDirectory(context.folderToStart)
}
// Drill as deep, as we can
while (currentName.componentCount > 0 && element == null) {
if (psiDirectory != null) { // Resolve against folder
// There could be folder and module on the same level. Empty folder should be ignored in this case.
element = resolveModuleAt(currentName, psiDirectory, resolveContext).filterNot {
it is PsiDirectory && it.children.filterIsInstance<PyFile>().isEmpty()
}.firstOrNull()
}
if (element == null) { // Resolve against roots
element = resolveQualifiedName(currentName, resolveContext).firstOrNull()
}
if (element != null || stopOnFirstFail) {
break
}
lastElement = currentName.lastComponent!!
currentName = currentName.removeLastComponent()
}
if (lastElement != null && element is PyClass) {
// Drill in class
//TODO: Support nested classes
val method = element.findMethodByName(lastElement, true, context.evalContext)
if (method != null) {
return NameAndElement(currentName.append(lastElement), method)
}
}
if (element == null && this.firstComponent != null && context.allowInaccurateResult) {
// If name starts with file which is not in root nor in folders -- use index.
val nameToFind = this.firstComponent!!
val pyFile = PyModuleNameIndex.find(nameToFind, context.contextAnchor.project, false).firstOrNull() ?: return element
val folder =
if (pyFile.name == PyNames.INIT_DOT_PY) { // We are in folder
pyFile.virtualFile.parent.parent
}
else {
pyFile.virtualFile.parent
}
return getElementAndResolvableName(context.copy(folderToStart = folder))
}
return if (element != null) NameAndElement(currentName, element) else null
}

View File

@@ -1,16 +0,0 @@
// Copyright 2000-2019 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license that can be found in the LICENSE file.
package com.jetbrains.extensions.python;
import com.jetbrains.python.nameResolver.FQNamesProvider
import com.jetbrains.python.nameResolver.NameResolverTools
import com.jetbrains.python.psi.PyCallExpression
import org.jetbrains.annotations.ApiStatus
/**
* @deprecated moved to {@link com.jetbrains.python.extensions}
*/
@ApiStatus.ScheduledForRemoval
@Deprecated(message = "Moved to com.jetbrains.python")
fun PyCallExpression.isCalleeName(vararg names: FQNamesProvider): Boolean = NameResolverTools.isCalleeShortCut(this, *names)

View File

@@ -1,9 +0,0 @@
// Copyright 2000-2024 JetBrains s.r.o. and contributors. Use of this source code is governed by the Apache 2.0 license.
/**
* @deprecated moved to {@link com.jetbrains.python.extensions}
*/
@ApiStatus.ScheduledForRemoval
@Deprecated
package com.jetbrains.extensions.python;
import org.jetbrains.annotations.ApiStatus;