[python] Inject requirements language into pyproject.toml (PY-42296, PY-54440)

GitOrigin-RevId: 196f56270d0a102a074872871898d640d77b2918
This commit is contained in:
lada.gagina
2024-01-08 16:36:32 +00:00
committed by intellij-monorepo-bot
parent df8937c7c2
commit e5166b993e
7 changed files with 79 additions and 4 deletions
+1 -4
View File
@@ -28,6 +28,7 @@
<lang.syntaxHighlighterFactory
language="Requirements"
implementationClass="com.intellij.python.community.impl.requirements.RequirementsSyntaxHighlighterFactory"/>
<multiHostInjector implementation="com.intellij.python.community.impl.requirements.RequirementsLanguageInjector"/>
<completion.contributor language="Requirements"
implementationClass="com.intellij.python.community.impl.requirements.RequirementsPackageNameCompletionContributor"/>
<completion.contributor language="Requirements"
@@ -542,10 +543,6 @@
key="python.sdk.installation.notification.group"/>
<completion.contributor language="TOML"
implementationClass="com.jetbrains.python.packaging.pyproject.PyprojectPackageCompletionContributor"/>
<completion.contributor language="TOML"
implementationClass="com.jetbrains.python.packaging.pyproject.PyprojectMetadataCompletionContributor"/>
<localInspection language="TOML"
shortName="PyprojectInspection"
suppressId="PyprojectInspection"
@@ -0,0 +1,34 @@
// 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.python.community.impl.requirements
import com.intellij.lang.injection.MultiHostInjector
import com.intellij.lang.injection.MultiHostRegistrar
import com.intellij.openapi.util.TextRange
import com.intellij.psi.PsiElement
import com.intellij.psi.PsiLanguageInjectionHost
import org.toml.lang.psi.TomlKeyValue
import org.toml.lang.psi.TomlLiteral
import org.toml.lang.psi.TomlTable
class RequirementsLanguageInjector : MultiHostInjector {
override fun getLanguagesToInject(registrar: MultiHostRegistrar, context: PsiElement) {
val parent = (context as TomlLiteral).parent.parent
if (parent is TomlKeyValue) {
if (parent.key.text == "dependencies" && "project" == (parent.parent as? TomlTable)?.header?.key?.text
|| parent.key.text == "requires" && "build-system" == (parent.parent as? TomlTable)?.header?.key?.text) {
registrar.startInjecting(RequirementsLanguage.INSTANCE).addPlace(null, null, context as PsiLanguageInjectionHost,
TextRange.create(1,
(context as PsiLanguageInjectionHost).textLength - 1)).doneInjecting()
}
}
}
override fun elementsToInjectIn(): MutableList<out Class<out PsiElement>> {
try {
return mutableListOf(TomlLiteral::class.java)
}
catch (exception: NoClassDefFoundError) {
return mutableListOf()
}
}
}
@@ -0,0 +1,2 @@
[build-system]
requires = [ "my<caret>" ]
@@ -0,0 +1,2 @@
[project]
dependencies = [ "my<caret>" ]
@@ -0,0 +1,2 @@
[build-system]
requires = [ "mypy==<caret>" ]
@@ -0,0 +1,2 @@
[project]
dependencies = [ "mypy==<caret>" ]
@@ -30,6 +30,24 @@ class RequirementsCompletionTest : BasePlatformTestCase() {
assertContainsElements(myFixture.lookupElementStrings!!, "mypy", "mypy-extensions")
}
fun testPackageNameInProjectTablePyProjectToml() {
mockPackageNames(listOf("mypy", "mypy-extensions"))
myFixture.configureByFile("${getTestName(true)}/pyproject.toml")
myFixture.completeBasic()
assertNotEmpty(myFixture.lookupElementStrings)
assertContainsElements(myFixture.lookupElementStrings!!, "mypy", "mypy-extensions")
}
fun testPackageNameInBuildSystemTablePyProjectToml() {
mockPackageNames(listOf("mypy", "mypy-extensions"))
myFixture.configureByFile("${getTestName(true)}/pyproject.toml")
myFixture.completeBasic()
assertNotEmpty(myFixture.lookupElementStrings)
assertContainsElements(myFixture.lookupElementStrings!!, "mypy", "mypy-extensions")
}
fun testVersionCompletion() {
mockPackageDetails("mypy", listOf("1.7.0", "1.6.1", "1.6.0"))
@@ -39,6 +57,24 @@ class RequirementsCompletionTest : BasePlatformTestCase() {
assertContainsOrdered(myFixture.lookupElementStrings!!, "1.7.0", "1.6.1", "1.6.0")
}
fun testVersionInBuildSystemTablePyProjectToml() {
mockPackageDetails("mypy", listOf("1.7.0", "1.6.1", "1.6.0"))
myFixture.configureByFile("${getTestName(true)}/pyproject.toml")
myFixture.completeBasic()
assertNotEmpty(myFixture.lookupElementStrings)
assertContainsOrdered(myFixture.lookupElementStrings!!, "1.7.0", "1.6.1", "1.6.0")
}
fun testVersionInProjectTablePyProjectToml() {
mockPackageDetails("mypy", listOf("1.7.0", "1.6.1", "1.6.0"))
myFixture.configureByFile("${getTestName(true)}/pyproject.toml")
myFixture.completeBasic()
assertNotEmpty(myFixture.lookupElementStrings)
assertContainsOrdered(myFixture.lookupElementStrings!!, "1.7.0", "1.6.1", "1.6.0")
}
private fun mockPackageNames(packageNames: List<String>) {
val packageManagerProvider = TestPackageManagerProvider().withPackageNames(packageNames)
ExtensionTestUtil.maskExtensions(PythonPackageManagerProvider.EP_NAME, listOf(packageManagerProvider), testRootDisposable)