From f7b998d57b81f2790db10103c829dc5d466d583d Mon Sep 17 00:00:00 2001 From: i582 <51853996+i582@users.noreply.github.com> Date: Fri, 10 Jun 2022 18:00:23 +0300 Subject: [PATCH] added initial support for class inherit --- .../exphptype/psi/ExPhpTypeInstancePsiImpl.kt | 4 +- .../com/vk/kphpstorm/generics/GenericCall.kt | 3 +- .../generics/GenericConstructorCall.kt | 2 +- .../kphpstorm/generics/GenericFunctionCall.kt | 1 + .../kphpstorm/generics/GenericMethodCall.kt | 14 +++- .../com/vk/kphpstorm/generics/GenericUtil.kt | 11 +++ .../vk/kphpstorm/generics/GenericsReifier.kt | 35 +++++++++ .../generics/ResolvingGenericBase.kt | 2 +- .../generics/ResolvingGenericMethodCall.kt | 61 +++++++++++++++- .../highlighting/KphpHighlightingData.kt | 1 + .../highlighting/KphpStormAnnotator.kt | 4 + .../psi/KphpDocInheritParameterDeclPsiImpl.kt | 12 +++ .../psi/KphpDocTagInheritElementType.kt | 14 +++- .../GenericClassesTypeProvider.kt | 16 ++++ .../colorSchemes/KphpAddonsDarcula.xml | 6 ++ .../colorSchemes/KphpAddonsDefault.xml | 6 ++ .../generics/general/inherit/main.fixture.php | 73 +++++++++++++++++++ .../generics/general/GenericsGeneralTest.kt | 4 + 18 files changed, 255 insertions(+), 14 deletions(-) create mode 100644 src/test/fixtures/generics/general/inherit/main.fixture.php diff --git a/src/main/kotlin/com/vk/kphpstorm/exphptype/psi/ExPhpTypeInstancePsiImpl.kt b/src/main/kotlin/com/vk/kphpstorm/exphptype/psi/ExPhpTypeInstancePsiImpl.kt index d71ca12..7bf840a 100644 --- a/src/main/kotlin/com/vk/kphpstorm/exphptype/psi/ExPhpTypeInstancePsiImpl.kt +++ b/src/main/kotlin/com/vk/kphpstorm/exphptype/psi/ExPhpTypeInstancePsiImpl.kt @@ -26,14 +26,14 @@ class ExPhpTypeInstancePsiImpl(node: ASTNode) : PhpDocTypeImpl(node) { PhpType().add(text) } - if (needBeGenericT(text)) { + if (isGenericT()) { return PhpType().add("%$text") } return getType(this, text) } - private fun needBeGenericT(text: String): Boolean { + fun isGenericT(): Boolean { val isGenericT = GenericUtil.nameIsGeneric(this, text) val phpDoc = parent.parent ?: return isGenericT diff --git a/src/main/kotlin/com/vk/kphpstorm/generics/GenericCall.kt b/src/main/kotlin/com/vk/kphpstorm/generics/GenericCall.kt index 9efd7cd..dd92382 100644 --- a/src/main/kotlin/com/vk/kphpstorm/generics/GenericCall.kt +++ b/src/main/kotlin/com/vk/kphpstorm/generics/GenericCall.kt @@ -51,6 +51,7 @@ abstract class GenericCall(val project: Project) { abstract val callArgs: Array abstract val explicitSpecsPsi: GenericInstantiationPsiCommentImpl? abstract val argumentsTypes: List + abstract val klass: PhpClass? protected var contextType: ExPhpType? = null abstract fun element(): PsiElement @@ -103,7 +104,7 @@ abstract class GenericCall(val project: Project) { // необходимы обв списка для дальнейших инспекций // В первую очередь, выводим все типы шаблонов из аргументов функции (при наличии) - reifier.reifyAllGenericsT(null, function.parameters, genericNames, argumentsTypes, contextType) + reifier.reifyAllGenericsT(klass, function.parameters, genericNames, argumentsTypes, contextType) // Далее, выводим все типы шаблонов из явного списка типов (при наличии) extractor.extractExplicitGenericsT(genericNames(), explicitSpecsPsi) } diff --git a/src/main/kotlin/com/vk/kphpstorm/generics/GenericConstructorCall.kt b/src/main/kotlin/com/vk/kphpstorm/generics/GenericConstructorCall.kt index b34992f..3fb6945 100644 --- a/src/main/kotlin/com/vk/kphpstorm/generics/GenericConstructorCall.kt +++ b/src/main/kotlin/com/vk/kphpstorm/generics/GenericConstructorCall.kt @@ -19,7 +19,7 @@ class GenericConstructorCall(private val call: NewExpression) : GenericCall(call .filterIsInstance().map { it.type.global(project).toExPhpType() } override val explicitSpecsPsi = GenericUtil.findInstantiationComment(call) - private val klass: PhpClass? + override val klass: PhpClass? private val method: Method? init { diff --git a/src/main/kotlin/com/vk/kphpstorm/generics/GenericFunctionCall.kt b/src/main/kotlin/com/vk/kphpstorm/generics/GenericFunctionCall.kt index eb76827..b1fa7ce 100644 --- a/src/main/kotlin/com/vk/kphpstorm/generics/GenericFunctionCall.kt +++ b/src/main/kotlin/com/vk/kphpstorm/generics/GenericFunctionCall.kt @@ -16,6 +16,7 @@ class GenericFunctionCall(private val call: FunctionReference) : GenericCall(cal override val argumentsTypes: List = callArgs .filterIsInstance().map { it.type.global(project).toExPhpType() } override val explicitSpecsPsi = findInstantiationComment(call) + override val klass = null private val function: Function? = call.resolve() as? Function diff --git a/src/main/kotlin/com/vk/kphpstorm/generics/GenericMethodCall.kt b/src/main/kotlin/com/vk/kphpstorm/generics/GenericMethodCall.kt index 2fdcc0e..b75bccb 100644 --- a/src/main/kotlin/com/vk/kphpstorm/generics/GenericMethodCall.kt +++ b/src/main/kotlin/com/vk/kphpstorm/generics/GenericMethodCall.kt @@ -1,8 +1,10 @@ package com.vk.kphpstorm.generics import com.intellij.psi.PsiElement +import com.jetbrains.php.PhpIndex import com.jetbrains.php.lang.psi.elements.Method import com.jetbrains.php.lang.psi.elements.MethodReference +import com.jetbrains.php.lang.psi.elements.PhpClass import com.jetbrains.php.lang.psi.elements.PhpTypedElement import com.jetbrains.php.lang.psi.resolve.types.PhpType import com.vk.kphpstorm.exphptype.ExPhpType @@ -19,7 +21,9 @@ class GenericMethodCall(private val call: MethodReference) : GenericCall(call.pr override val explicitSpecsPsi = GenericUtil.findInstantiationComment(call) private val method = call.resolve() as? Method - private val klass = method?.containingClass + // TODO + private val containingClass = method?.containingClass + override val klass: PhpClass? init { val callType = call.classReference?.type?.global(project) @@ -27,11 +31,11 @@ class GenericMethodCall(private val call: MethodReference) : GenericCall(call.pr val classType = PhpType().add(callType).global(project) val parsed = classType.toExPhpType() - val instantiation = parsed?.getInstantiations()?.firstOrNull { - it.classFqn == klass?.fqn - } + val instantiation = parsed?.getInstantiations()?.firstOrNull() if (instantiation != null) { + klass = PhpIndex.getInstance(project).getAnyByFQN(instantiation.classFqn).firstOrNull() + val specialization = instantiation.specializationList val classSpecializationNameMap = mutableMapOf() val genericNames = klass?.genericNames() ?: emptyList() @@ -43,6 +47,8 @@ class GenericMethodCall(private val call: MethodReference) : GenericCall(call.pr classSpecializationNameMap.forEach { (name, type) -> reifier.implicitClassSpecializationNameMap[name] = type } + } else { + klass = null } init() diff --git a/src/main/kotlin/com/vk/kphpstorm/generics/GenericUtil.kt b/src/main/kotlin/com/vk/kphpstorm/generics/GenericUtil.kt index 0c61900..f322f03 100644 --- a/src/main/kotlin/com/vk/kphpstorm/generics/GenericUtil.kt +++ b/src/main/kotlin/com/vk/kphpstorm/generics/GenericUtil.kt @@ -13,7 +13,9 @@ import com.jetbrains.php.lang.psi.resolve.types.PhpType import com.vk.kphpstorm.exphptype.* import com.vk.kphpstorm.generics.psi.GenericInstantiationPsiCommentImpl import com.vk.kphpstorm.kphptags.psi.KphpDocGenericParameterDecl +import com.vk.kphpstorm.kphptags.psi.KphpDocInheritParameterDeclPsiImpl import com.vk.kphpstorm.kphptags.psi.KphpDocTagGenericPsiImpl +import com.vk.kphpstorm.kphptags.psi.KphpDocTagInheritPsiImpl object GenericUtil { fun PhpNamedElement.isGeneric() = docComment?.getTagElementsByName("@kphp-generic")?.firstOrNull() != null @@ -60,6 +62,15 @@ object GenericUtil { return extendsList.filter { it.isGeneric() } to implementsList.filter { it.isGeneric() } } + fun PhpClass.genericInheritInstantiation(className: String): KphpDocInheritParameterDeclPsiImpl? { + val docT = docComment?.getTagElementsByName("@kphp-inherit")?.firstOrNull() as? KphpDocTagInheritPsiImpl + ?: return null + + return docT.types().find { + it.className() == className + } + } + fun ExPhpType.isGenericPipe(): Boolean { if (this is ExPhpTypePipe) { if (this.items.size != 2) return false diff --git a/src/main/kotlin/com/vk/kphpstorm/generics/GenericsReifier.kt b/src/main/kotlin/com/vk/kphpstorm/generics/GenericsReifier.kt index 9315893..9cc6a67 100644 --- a/src/main/kotlin/com/vk/kphpstorm/generics/GenericsReifier.kt +++ b/src/main/kotlin/com/vk/kphpstorm/generics/GenericsReifier.kt @@ -5,6 +5,9 @@ import com.jetbrains.php.lang.psi.elements.Parameter import com.jetbrains.php.lang.psi.elements.PhpClass import com.jetbrains.php.lang.psi.elements.PhpTypedElement import com.vk.kphpstorm.exphptype.* +import com.vk.kphpstorm.generics.GenericUtil.genericInheritInstantiation +import com.vk.kphpstorm.generics.GenericUtil.genericNames +import com.vk.kphpstorm.generics.GenericUtil.genericParents import com.vk.kphpstorm.generics.GenericUtil.getGenericTypeOrSelf import com.vk.kphpstorm.generics.GenericUtil.getInstantiation import com.vk.kphpstorm.generics.GenericUtil.isGeneric @@ -81,6 +84,38 @@ class GenericsReifier(val project: Project) { implicitSpecs.add(type) } implicitSpecializationNameMap.putAll(implicitClassSpecializationNameMap) + + if (klass != null) { + val (extendsList, implementsList) = klass.genericParents() + + val parentsList = extendsList + implementsList + parentsList.forEach { parent -> + val extendsName = parent.fqn + val genericNames = parent.genericNames() + val inheritInstantiation = klass.genericInheritInstantiation(extendsName) + if (inheritInstantiation != null) { + val specList = inheritInstantiation.specializationList() + + val classSpecializationMap = genericNames.associate { + it.name to it.defaultType + }.toMutableMap() + + for (i in 0 until Integer.min(genericNames.size, specList.size)) { + val genericT = genericNames[i] + val spec = specList[i] + + classSpecializationMap[genericT.name] = spec + } + + classSpecializationMap.forEach classForEach@{ (name, type) -> + if (type == null) { + return@classForEach + } + implicitSpecializationNameMap[name] = type.instantiateGeneric(implicitSpecializationNameMap) + } + } + } + } } /** diff --git a/src/main/kotlin/com/vk/kphpstorm/generics/ResolvingGenericBase.kt b/src/main/kotlin/com/vk/kphpstorm/generics/ResolvingGenericBase.kt index 55db4a7..ddb9573 100644 --- a/src/main/kotlin/com/vk/kphpstorm/generics/ResolvingGenericBase.kt +++ b/src/main/kotlin/com/vk/kphpstorm/generics/ResolvingGenericBase.kt @@ -41,7 +41,7 @@ abstract class ResolvingGenericBase(val project: Project) { return instantiate() } - protected fun specialization(): Map { + protected fun specialization(): MutableMap { val specialization = specializationList() val specializationNameMap = mutableMapOf() diff --git a/src/main/kotlin/com/vk/kphpstorm/generics/ResolvingGenericMethodCall.kt b/src/main/kotlin/com/vk/kphpstorm/generics/ResolvingGenericMethodCall.kt index 9e3376a..5ce5f41 100644 --- a/src/main/kotlin/com/vk/kphpstorm/generics/ResolvingGenericMethodCall.kt +++ b/src/main/kotlin/com/vk/kphpstorm/generics/ResolvingGenericMethodCall.kt @@ -2,18 +2,23 @@ package com.vk.kphpstorm.generics import com.intellij.openapi.project.Project import com.jetbrains.php.PhpIndex +import com.jetbrains.php.lang.documentation.phpdoc.psi.tags.PhpDocReturnTag import com.jetbrains.php.lang.psi.elements.Method import com.jetbrains.php.lang.psi.elements.Parameter import com.jetbrains.php.lang.psi.elements.PhpClass +import com.jetbrains.php.lang.psi.elements.impl.PhpClassImpl import com.jetbrains.php.lang.psi.resolve.types.PhpType import com.vk.kphpstorm.exphptype.ExPhpTypeGenericsT import com.vk.kphpstorm.exphptype.ExPhpTypeTplInstantiation +import com.vk.kphpstorm.generics.GenericUtil.genericInheritInstantiation import com.vk.kphpstorm.generics.GenericUtil.genericNames +import com.vk.kphpstorm.generics.GenericUtil.genericParents import com.vk.kphpstorm.generics.GenericUtil.getInstantiations import com.vk.kphpstorm.generics.GenericUtil.isReturnGeneric import com.vk.kphpstorm.helpers.toExPhpType import com.vk.kphpstorm.kphptags.psi.KphpDocGenericParameterDecl import com.vk.kphpstorm.typeProviders.GenericMethodsTypeProvider +import java.lang.Integer.min class ResolvingGenericMethodCall(project: Project) : ResolvingGenericBase(project) { override var klass: PhpClass? = null @@ -25,10 +30,62 @@ class ResolvingGenericMethodCall(project: Project) : ResolvingGenericBase(projec override var classGenericType: ExPhpTypeTplInstantiation? = null override fun instantiate(): PhpType? { + val klass = klass ?: return null + val specializationNameMap = specialization() - val returnTag = method?.docComment?.returnTag ?: return null - val exType = returnTag.type.toExPhpType(project) ?: return null + val (extendsList, implementsList) = klass.genericParents() + + val parentsList = extendsList + implementsList + parentsList.forEach { parent -> + val extendsName = parent.fqn + val genericNames = parent.genericNames() + val inheritInstantiation = klass.genericInheritInstantiation(extendsName) + if (inheritInstantiation != null) { + val specList = inheritInstantiation.specializationList() + + val classSpecializationMap = genericNames.associate { + it.name to it.defaultType + }.toMutableMap() + + for (i in 0 until min(genericNames.size, specList.size)) { + val genericT = genericNames[i] + val spec = specList[i] + + classSpecializationMap[genericT.name] = spec + } + + classSpecializationMap.forEach classForEach@{ (name, type) -> + if (type == null) { + return@classForEach + } + specializationNameMap[name] = type.instantiateGeneric(specializationNameMap) + } + } + } + + val classImpl = klass as PhpClassImpl + + var returnTag: PhpDocReturnTag? = null + + val ifaces = classImpl.directImplementedInterfaces + ifaces.forEach { iface -> + val method = iface.findMethodByName(method!!.name) + returnTag = method?.docComment?.returnTag ?: return@forEach + } + + val classes = listOf(classImpl.superClass) + classes.forEach { parent -> + val method = parent?.findMethodByName(method!!.name) + returnTag = method?.docComment?.returnTag ?: return@forEach + } + + val classMethodReturnTag = method?.docComment?.returnTag + if (classMethodReturnTag != null) { + returnTag = classMethodReturnTag + } + + val exType = returnTag?.type?.toExPhpType(project) ?: return null val specializedType = exType.instantiateGeneric(specializationNameMap) return specializedType.toPhpType() diff --git a/src/main/kotlin/com/vk/kphpstorm/highlighting/KphpHighlightingData.kt b/src/main/kotlin/com/vk/kphpstorm/highlighting/KphpHighlightingData.kt index 8dbf374..e8e9014 100644 --- a/src/main/kotlin/com/vk/kphpstorm/highlighting/KphpHighlightingData.kt +++ b/src/main/kotlin/com/vk/kphpstorm/highlighting/KphpHighlightingData.kt @@ -13,6 +13,7 @@ object KphpHighlightingData { val PHPDOC_TAG_KPHP = TextAttributesKey.createTextAttributesKey("PHPDOC_TAG_KPHP", PhpHighlightingData.DOC_TAG) val PHPDOC_TAG_REGULAR = TextAttributesKey.createTextAttributesKey("PHPDOC_TAG_REGULAR", PhpHighlightingData.DOC_TAG) val PHPDOC_TYPE_INSIDE = TextAttributesKey.createTextAttributesKey("PHPDOC_TYPE_INSIDE", PhpHighlightingData.DOC_IDENTIFIER) + val PHPDOC_GENERIC_TYPE_T = TextAttributesKey.createTextAttributesKey("PHPDOC_GENERIC_TYPE_T", PhpHighlightingData.DOC_IDENTIFIER) val FUNC_CALL_REGULAR = TextAttributesKey.createTextAttributesKey("FUNC_CALL_REGULAR", PhpHighlightingData.FUNCTION_CALL) val FUNC_CALL_KPHP_NATIVE = TextAttributesKey.createTextAttributesKey("FUNC_CALL_KPHP_NATIVE", PhpHighlightingData.FUNCTION_CALL) diff --git a/src/main/kotlin/com/vk/kphpstorm/highlighting/KphpStormAnnotator.kt b/src/main/kotlin/com/vk/kphpstorm/highlighting/KphpStormAnnotator.kt index 327547d..a59b875 100644 --- a/src/main/kotlin/com/vk/kphpstorm/highlighting/KphpStormAnnotator.kt +++ b/src/main/kotlin/com/vk/kphpstorm/highlighting/KphpStormAnnotator.kt @@ -20,6 +20,7 @@ import com.jetbrains.php.lang.psi.elements.PhpClass import com.jetbrains.php.lang.psi.elements.impl.ClassReferenceImpl import com.jetbrains.php.lang.psi.elements.impl.FunctionReferenceImpl import com.jetbrains.php.lang.psi.resolve.types.PhpType +import com.vk.kphpstorm.exphptype.psi.ExPhpTypeInstancePsiImpl import com.vk.kphpstorm.helpers.KPHP_NATIVE_FUNCTIONS import com.vk.kphpstorm.kphptags.ALL_KPHPDOC_TAGS import com.vk.kphpstorm.kphptags.psi.KphpDocTagImpl @@ -122,6 +123,9 @@ class KphpStormAnnotator : Annotator { @Suppress("UNUSED_PARAMETER") private fun onTypeInsidePhpdocTag(element: PhpDocTypeImpl, holder: AnnotationHolder) { // for future: highlight primitives and classes, template args and shape keys + if (element is ExPhpTypeInstancePsiImpl && element.isGenericT()) { + holder.textAttributes(element, KphpHighlightingData.PHPDOC_GENERIC_TYPE_T) + } } /** diff --git a/src/main/kotlin/com/vk/kphpstorm/kphptags/psi/KphpDocInheritParameterDeclPsiImpl.kt b/src/main/kotlin/com/vk/kphpstorm/kphptags/psi/KphpDocInheritParameterDeclPsiImpl.kt index f030ae1..7dbc32d 100644 --- a/src/main/kotlin/com/vk/kphpstorm/kphptags/psi/KphpDocInheritParameterDeclPsiImpl.kt +++ b/src/main/kotlin/com/vk/kphpstorm/kphptags/psi/KphpDocInheritParameterDeclPsiImpl.kt @@ -5,6 +5,7 @@ import com.jetbrains.php.lang.documentation.phpdoc.psi.PhpDocElementType import com.jetbrains.php.lang.documentation.phpdoc.psi.PhpDocRef import com.jetbrains.php.lang.documentation.phpdoc.psi.impl.PhpDocPsiElementImpl import com.jetbrains.php.lang.documentation.phpdoc.psi.impl.PhpDocTypeImpl +import com.vk.kphpstorm.exphptype.ExPhpType import com.vk.kphpstorm.exphptype.ExPhpTypeInstance import com.vk.kphpstorm.exphptype.ExPhpTypeTplInstantiation import com.vk.kphpstorm.exphptype.psi.ExPhpTypeInstancePsiImpl @@ -36,4 +37,15 @@ class KphpDocInheritParameterDeclPsiImpl(node: ASTNode) : PhpDocPsiElementImpl(n return exType.getInstantiation()?.classFqn } + + fun specializationList(): List { + val instantiationPsi = findChildByClass(PhpDocTypeImpl::class.java) ?: return emptyList() + if (instantiationPsi !is ExPhpTypeTplInstantiationPsiImpl) + return emptyList() + + val exType = instantiationPsi.type.toExPhpType() ?: return emptyList() + val instantiation = exType.getInstantiation() ?: return emptyList() + + return instantiation.specializationList + } } diff --git a/src/main/kotlin/com/vk/kphpstorm/kphptags/psi/KphpDocTagInheritElementType.kt b/src/main/kotlin/com/vk/kphpstorm/kphptags/psi/KphpDocTagInheritElementType.kt index 878802b..c66fd1e 100644 --- a/src/main/kotlin/com/vk/kphpstorm/kphptags/psi/KphpDocTagInheritElementType.kt +++ b/src/main/kotlin/com/vk/kphpstorm/kphptags/psi/KphpDocTagInheritElementType.kt @@ -26,9 +26,17 @@ object KphpDocTagInheritElementType : } override fun createStub(psi: PhpDocTag, parentStub: StubElement<*>?): PhpDocTagStub { - // stub value is 'T1,T2:ExtendsClass,T2=default' — without spaces - // TODO: add stubs - return KphpDocTagStubImpl(parentStub, this, psi.name, "stubValue") + val stubValue = (psi as KphpDocTagInheritPsiImpl).types() + .joinToString(",") { + val type = StringBuilder() + + if (it.className() != null) { + type.append(it.className().toString()) + } + + type.toString() + } + return KphpDocTagStubImpl(parentStub, this, psi.name, stubValue) } override fun serialize(stub: PhpDocTagStub, dataStream: StubOutputStream) { diff --git a/src/main/kotlin/com/vk/kphpstorm/typeProviders/GenericClassesTypeProvider.kt b/src/main/kotlin/com/vk/kphpstorm/typeProviders/GenericClassesTypeProvider.kt index 0b8b623..3bb7ca3 100644 --- a/src/main/kotlin/com/vk/kphpstorm/typeProviders/GenericClassesTypeProvider.kt +++ b/src/main/kotlin/com/vk/kphpstorm/typeProviders/GenericClassesTypeProvider.kt @@ -2,10 +2,15 @@ package com.vk.kphpstorm.typeProviders import com.intellij.openapi.project.Project import com.intellij.psi.PsiElement +import com.intellij.psi.util.parentOfType +import com.jetbrains.php.lang.psi.elements.ClassReference import com.jetbrains.php.lang.psi.elements.NewExpression +import com.jetbrains.php.lang.psi.elements.PhpClass import com.jetbrains.php.lang.psi.resolve.types.PhpCharTypeKey import com.jetbrains.php.lang.psi.resolve.types.PhpType import com.jetbrains.php.lang.psi.resolve.types.PhpTypeProvider4 +import com.vk.kphpstorm.exphptype.psi.ExPhpTypeTplInstantiationPsiImpl +import com.vk.kphpstorm.generics.GenericUtil.genericInheritInstantiation import com.vk.kphpstorm.generics.IndexingGenericFunctionCall import com.vk.kphpstorm.generics.ResolvingGenericConstructorCall @@ -26,6 +31,17 @@ class GenericClassesTypeProvider : PhpTypeProvider4 { return PhpType().add(KEY.sign(data)) } + if (p is ClassReference && p.name == "parent") { + val containingClass = p.parentOfType() + if (containingClass != null) { + val superClass = containingClass.extendsList.referenceElements.firstOrNull() ?: return null + val superClassName = superClass.fqn ?: return null + val instantiationParameter = containingClass.genericInheritInstantiation(superClassName) + val instantiation = instantiationParameter?.firstChild as? ExPhpTypeTplInstantiationPsiImpl + return instantiation?.type + } + } + return null } diff --git a/src/main/resources/colorSchemes/KphpAddonsDarcula.xml b/src/main/resources/colorSchemes/KphpAddonsDarcula.xml index c3aeb6a..089c7bd 100644 --- a/src/main/resources/colorSchemes/KphpAddonsDarcula.xml +++ b/src/main/resources/colorSchemes/KphpAddonsDarcula.xml @@ -21,6 +21,12 @@ + +