From 9e35148697221c3bc1abb70b84b67e2af8c601e2 Mon Sep 17 00:00:00 2001 From: Robert Novotny Date: Wed, 31 Jul 2024 09:49:43 +0200 Subject: [PATCH 1/5] Add verifier for languageBundle EP --- .../intellij/plugin/PluginCreator.kt | 2 + .../intellij/problems/UnacceptableWarnings.kt | 14 ++++- .../verifiers/ExtensionPointVerifiers.kt | 18 ++++++ .../verifiers/LanguageBundleEpVerifierTest.kt | 58 +++++++++++++++++++ .../plugin/structure/mocks/Extensions.kt | 22 +++++++ 5 files changed, 113 insertions(+), 1 deletion(-) create mode 100644 intellij-plugin-structure/tests/src/test/kotlin/com/jetbrains/plugin/structure/intellij/verifiers/LanguageBundleEpVerifierTest.kt create mode 100644 intellij-plugin-structure/tests/src/test/kotlin/com/jetbrains/plugin/structure/mocks/Extensions.kt diff --git a/intellij-plugin-structure/structure-intellij/src/main/java/com/jetbrains/plugin/structure/intellij/plugin/PluginCreator.kt b/intellij-plugin-structure/structure-intellij/src/main/java/com/jetbrains/plugin/structure/intellij/plugin/PluginCreator.kt index d9c22f80e..0a130ec36 100644 --- a/intellij-plugin-structure/structure-intellij/src/main/java/com/jetbrains/plugin/structure/intellij/plugin/PluginCreator.kt +++ b/intellij-plugin-structure/structure-intellij/src/main/java/com/jetbrains/plugin/structure/intellij/plugin/PluginCreator.kt @@ -30,6 +30,7 @@ import com.jetbrains.plugin.structure.intellij.beans.ProductDescriptorBean import com.jetbrains.plugin.structure.intellij.extractor.PluginBeanExtractor import com.jetbrains.plugin.structure.intellij.problems.* import com.jetbrains.plugin.structure.intellij.resources.ResourceResolver +import com.jetbrains.plugin.structure.intellij.verifiers.LanguageBundleExtensionPointVerifier import com.jetbrains.plugin.structure.intellij.verifiers.PluginIdVerifier import com.jetbrains.plugin.structure.intellij.verifiers.PluginUntilBuildVerifier import com.jetbrains.plugin.structure.intellij.verifiers.ReusedDescriptorVerifier @@ -682,6 +683,7 @@ internal class PluginCreator private constructor( ServiceExtensionPointPreloadVerifier().verify(plugin, ::registerProblem) StatusBarWidgetFactoryExtensionPointVerifier().verify(plugin, ::registerProblem) + LanguageBundleExtensionPointVerifier().verify(plugin, ::registerProblem) } private fun resolveDocumentAndValidateBean( diff --git a/intellij-plugin-structure/structure-intellij/src/main/java/com/jetbrains/plugin/structure/intellij/problems/UnacceptableWarnings.kt b/intellij-plugin-structure/structure-intellij/src/main/java/com/jetbrains/plugin/structure/intellij/problems/UnacceptableWarnings.kt index 8e0551947..3efdecf7e 100644 --- a/intellij-plugin-structure/structure-intellij/src/main/java/com/jetbrains/plugin/structure/intellij/problems/UnacceptableWarnings.kt +++ b/intellij-plugin-structure/structure-intellij/src/main/java/com/jetbrains/plugin/structure/intellij/problems/UnacceptableWarnings.kt @@ -1,7 +1,7 @@ package com.jetbrains.plugin.structure.intellij.problems -import com.jetbrains.plugin.structure.base.problems.PluginProblem import com.jetbrains.plugin.structure.base.problems.InvalidDescriptorProblem +import com.jetbrains.plugin.structure.base.problems.PluginProblem import com.jetbrains.plugin.structure.base.problems.ProblemSolutionHint import com.jetbrains.plugin.structure.intellij.plugin.IdePluginContentDescriptor @@ -56,6 +56,18 @@ class StatusBarWidgetFactoryExtensionPointIdMissing(private val implementationCl "value returned from the getId() method of the $implementationClassFqn implementation." } +class LanguageBundleExtensionPointIsInternal : PluginProblem() { + private val extensionPointName = "com.intellij.languageBundle" + + override val level + get() = Level.UNACCEPTABLE_WARNING + + override val message + get() = "The extension point in the <${extensionPointName}> element is internal " + + "and must be used by JetBrains only." +} + + class NoDependencies(descriptorPath: String) : InvalidDescriptorProblem( descriptorPath = descriptorPath, detailedMessage = "Plugin has no dependencies. Please check the documentation: https://plugins.jetbrains.com/docs/intellij/plugin-compatibility.html" diff --git a/intellij-plugin-structure/structure-intellij/src/main/java/com/jetbrains/plugin/structure/intellij/verifiers/ExtensionPointVerifiers.kt b/intellij-plugin-structure/structure-intellij/src/main/java/com/jetbrains/plugin/structure/intellij/verifiers/ExtensionPointVerifiers.kt index a56e703a0..2eccb248c 100644 --- a/intellij-plugin-structure/structure-intellij/src/main/java/com/jetbrains/plugin/structure/intellij/verifiers/ExtensionPointVerifiers.kt +++ b/intellij-plugin-structure/structure-intellij/src/main/java/com/jetbrains/plugin/structure/intellij/verifiers/ExtensionPointVerifiers.kt @@ -3,6 +3,8 @@ package com.jetbrains.plugin.structure.intellij.verifiers import com.jetbrains.plugin.structure.intellij.plugin.IdePlugin import com.jetbrains.plugin.structure.intellij.plugin.IdePluginContentDescriptor import com.jetbrains.plugin.structure.intellij.plugin.IdePluginContentDescriptor.ServiceDescriptor +import com.jetbrains.plugin.structure.intellij.plugin.PluginVendors.isDevelopedByJetBrains +import com.jetbrains.plugin.structure.intellij.problems.LanguageBundleExtensionPointIsInternal import com.jetbrains.plugin.structure.intellij.problems.ServiceExtensionPointPreloadNotSupported import com.jetbrains.plugin.structure.intellij.problems.StatusBarWidgetFactoryExtensionPointIdMissing @@ -46,4 +48,20 @@ class StatusBarWidgetFactoryExtensionPointVerifier { } } } +} + +/** + * Rule: EP `com.intellij.languageBundle` is internal and must be used by JetBrains only. + */ +class LanguageBundleExtensionPointVerifier { + private val extensionPointName = "com.intellij.languageBundle" + + fun verify(plugin: IdePlugin, problemRegistrar: ProblemRegistrar) { + if (!isDevelopedByJetBrains(plugin)) { + val languageBundles = plugin.extensions[extensionPointName] ?: emptyList() + if (languageBundles.isNotEmpty()) { + problemRegistrar.registerProblem(LanguageBundleExtensionPointIsInternal()) + } + } + } } \ No newline at end of file diff --git a/intellij-plugin-structure/tests/src/test/kotlin/com/jetbrains/plugin/structure/intellij/verifiers/LanguageBundleEpVerifierTest.kt b/intellij-plugin-structure/tests/src/test/kotlin/com/jetbrains/plugin/structure/intellij/verifiers/LanguageBundleEpVerifierTest.kt new file mode 100644 index 000000000..aad23c63e --- /dev/null +++ b/intellij-plugin-structure/tests/src/test/kotlin/com/jetbrains/plugin/structure/intellij/verifiers/LanguageBundleEpVerifierTest.kt @@ -0,0 +1,58 @@ +package com.jetbrains.plugin.structure.intellij.verifiers + +import com.jetbrains.plugin.structure.base.problems.PluginProblem +import com.jetbrains.plugin.structure.intellij.plugin.IdePluginImpl +import com.jetbrains.plugin.structure.mocks.MockExtension +import org.junit.Assert.assertEquals +import org.junit.Before +import org.junit.Test + +private const val PLUGIN_ID = "com.example.thirdparty" +private const val PLUGIN_VENDOR = "PluginIndustries s.r.o." +private const val JETBRAINS_PLUGIN_VENDOR = "JetBrains" +private const val MESSAGE_TEMPLATE = "The extension point in the element is internal and must be used by JetBrains only." + + +class LanguageBundleEpVerifierTest { + private lateinit var verifier: LanguageBundleExtensionPointVerifier + + private lateinit var problems: MutableList + + private val problemRegistrar = ProblemRegistrar { + problems += it + } + + @Before + fun setUp() { + verifier = LanguageBundleExtensionPointVerifier() + problems = mutableListOf() + } + + @Test + fun `plugin is not allowed to use languageBundle EP`() { + val extension = MockExtension.from("languageBundle", "locale" to "en-US") + + val idePlugin = IdePluginImpl().apply { + pluginId = PLUGIN_ID + vendor = PLUGIN_VENDOR + extension.apply(this) + } + verifier.verify(idePlugin, problemRegistrar) + assertEquals(1, problems.size) + val problem = problems[0] + assertEquals(MESSAGE_TEMPLATE, problem.message) + } + + @Test + fun `JetBrains plugin is allowed to use languageBundle EP`() { + val extension = MockExtension.from("languageBundle", "locale" to "en-US") + + val idePlugin = IdePluginImpl().apply { + pluginId = PLUGIN_ID + vendor = JETBRAINS_PLUGIN_VENDOR + extension.apply(this) + } + verifier.verify(idePlugin, problemRegistrar) + assertEquals(0, problems.size) + } +} \ No newline at end of file diff --git a/intellij-plugin-structure/tests/src/test/kotlin/com/jetbrains/plugin/structure/mocks/Extensions.kt b/intellij-plugin-structure/tests/src/test/kotlin/com/jetbrains/plugin/structure/mocks/Extensions.kt new file mode 100644 index 000000000..43834839d --- /dev/null +++ b/intellij-plugin-structure/tests/src/test/kotlin/com/jetbrains/plugin/structure/mocks/Extensions.kt @@ -0,0 +1,22 @@ +package com.jetbrains.plugin.structure.mocks + +import com.jetbrains.plugin.structure.intellij.plugin.IdePluginImpl +import org.jdom2.Element + +class MockExtension(private val fullyQualifiedName: String, private val elements: List) { + fun apply(plugin: IdePluginImpl) { + plugin.extensions[fullyQualifiedName] = elements.toMutableList() + } + + companion object { + fun from(extensionLocalName: String, vararg attributes: Pair): MockExtension { + val extensionFqn = "com.intellij.$extensionLocalName" + val element = Element(extensionFqn).apply { + for ((attrName, attrValue) in attributes) { + setAttribute(attrName, attrValue) + } + } + return MockExtension(extensionFqn, listOf(element)) + } + } +} From 668a99ebb4f99c41d2b7b1459907a4f9bdd82598 Mon Sep 17 00:00:00 2001 From: Robert Novotny Date: Wed, 31 Jul 2024 10:10:05 +0200 Subject: [PATCH 2/5] Introduce in-memory problem registrar --- .../structure/mocks/SimpleProblemRegistrar.kt | 19 +++++++++++++++++++ 1 file changed, 19 insertions(+) create mode 100644 intellij-plugin-structure/tests/src/test/kotlin/com/jetbrains/plugin/structure/mocks/SimpleProblemRegistrar.kt diff --git a/intellij-plugin-structure/tests/src/test/kotlin/com/jetbrains/plugin/structure/mocks/SimpleProblemRegistrar.kt b/intellij-plugin-structure/tests/src/test/kotlin/com/jetbrains/plugin/structure/mocks/SimpleProblemRegistrar.kt new file mode 100644 index 000000000..b61b772b1 --- /dev/null +++ b/intellij-plugin-structure/tests/src/test/kotlin/com/jetbrains/plugin/structure/mocks/SimpleProblemRegistrar.kt @@ -0,0 +1,19 @@ +package com.jetbrains.plugin.structure.mocks + +import com.jetbrains.plugin.structure.base.problems.PluginProblem +import com.jetbrains.plugin.structure.intellij.verifiers.ProblemRegistrar + +class SimpleProblemRegistrar : ProblemRegistrar { + private val _problems = mutableListOf() + + val problems: List + get() = _problems + + override fun registerProblem(problem: PluginProblem) { + _problems += problem + } + + fun reset() { + _problems.clear() + } +} \ No newline at end of file From adb26fa1e99701b0f9ed5c561c4e40b83e82ba5b Mon Sep 17 00:00:00 2001 From: Robert Novotny Date: Wed, 31 Jul 2024 10:10:42 +0200 Subject: [PATCH 3/5] Extract common EP behavior into parent class --- .../verifiers/BaseExtensionPointTest.kt | 22 +++++++++++++++++++ .../verifiers/LanguageBundleEpVerifierTest.kt | 21 +----------------- ...erviceExtensionPointPreloadVerifierTest.kt | 21 ++---------------- ...WidgetFactoryExtensionPointVerifierTest.kt | 21 ++---------------- 4 files changed, 27 insertions(+), 58 deletions(-) create mode 100644 intellij-plugin-structure/tests/src/test/kotlin/com/jetbrains/plugin/structure/intellij/verifiers/BaseExtensionPointTest.kt diff --git a/intellij-plugin-structure/tests/src/test/kotlin/com/jetbrains/plugin/structure/intellij/verifiers/BaseExtensionPointTest.kt b/intellij-plugin-structure/tests/src/test/kotlin/com/jetbrains/plugin/structure/intellij/verifiers/BaseExtensionPointTest.kt new file mode 100644 index 000000000..5383c2f14 --- /dev/null +++ b/intellij-plugin-structure/tests/src/test/kotlin/com/jetbrains/plugin/structure/intellij/verifiers/BaseExtensionPointTest.kt @@ -0,0 +1,22 @@ +package com.jetbrains.plugin.structure.intellij.verifiers + +import com.jetbrains.plugin.structure.base.problems.PluginProblem +import com.jetbrains.plugin.structure.mocks.SimpleProblemRegistrar +import org.junit.Before + +internal const val PLUGIN_ID = "com.example.thirdparty" +internal const val PLUGIN_VENDOR = "PluginIndustries s.r.o." +internal const val JETBRAINS_PLUGIN_VENDOR = "JetBrains" + +abstract class BaseExtensionPointTest(val verifier: V) { + + protected val problemRegistrar = SimpleProblemRegistrar() + + protected val problems: List + get() = problemRegistrar.problems + + @Before + fun setUp() { + problemRegistrar.reset() + } +} \ No newline at end of file diff --git a/intellij-plugin-structure/tests/src/test/kotlin/com/jetbrains/plugin/structure/intellij/verifiers/LanguageBundleEpVerifierTest.kt b/intellij-plugin-structure/tests/src/test/kotlin/com/jetbrains/plugin/structure/intellij/verifiers/LanguageBundleEpVerifierTest.kt index aad23c63e..41e4d0cbd 100644 --- a/intellij-plugin-structure/tests/src/test/kotlin/com/jetbrains/plugin/structure/intellij/verifiers/LanguageBundleEpVerifierTest.kt +++ b/intellij-plugin-structure/tests/src/test/kotlin/com/jetbrains/plugin/structure/intellij/verifiers/LanguageBundleEpVerifierTest.kt @@ -1,32 +1,13 @@ package com.jetbrains.plugin.structure.intellij.verifiers -import com.jetbrains.plugin.structure.base.problems.PluginProblem import com.jetbrains.plugin.structure.intellij.plugin.IdePluginImpl import com.jetbrains.plugin.structure.mocks.MockExtension import org.junit.Assert.assertEquals -import org.junit.Before import org.junit.Test -private const val PLUGIN_ID = "com.example.thirdparty" -private const val PLUGIN_VENDOR = "PluginIndustries s.r.o." -private const val JETBRAINS_PLUGIN_VENDOR = "JetBrains" private const val MESSAGE_TEMPLATE = "The extension point in the element is internal and must be used by JetBrains only." - -class LanguageBundleEpVerifierTest { - private lateinit var verifier: LanguageBundleExtensionPointVerifier - - private lateinit var problems: MutableList - - private val problemRegistrar = ProblemRegistrar { - problems += it - } - - @Before - fun setUp() { - verifier = LanguageBundleExtensionPointVerifier() - problems = mutableListOf() - } +class LanguageBundleEpVerifierTest : BaseExtensionPointTest(LanguageBundleExtensionPointVerifier()) { @Test fun `plugin is not allowed to use languageBundle EP`() { diff --git a/intellij-plugin-structure/tests/src/test/kotlin/com/jetbrains/plugin/structure/intellij/verifiers/ServiceExtensionPointPreloadVerifierTest.kt b/intellij-plugin-structure/tests/src/test/kotlin/com/jetbrains/plugin/structure/intellij/verifiers/ServiceExtensionPointPreloadVerifierTest.kt index d5b77edb6..5f7c8111f 100644 --- a/intellij-plugin-structure/tests/src/test/kotlin/com/jetbrains/plugin/structure/intellij/verifiers/ServiceExtensionPointPreloadVerifierTest.kt +++ b/intellij-plugin-structure/tests/src/test/kotlin/com/jetbrains/plugin/structure/intellij/verifiers/ServiceExtensionPointPreloadVerifierTest.kt @@ -1,34 +1,17 @@ package com.jetbrains.plugin.structure.intellij.verifiers -import com.jetbrains.plugin.structure.base.problems.PluginProblem import com.jetbrains.plugin.structure.intellij.plugin.IdePluginContentDescriptor.* import com.jetbrains.plugin.structure.intellij.plugin.IdePluginImpl import org.junit.Assert import org.junit.Assert.assertEquals -import org.junit.Before import org.junit.Test -private const val PLUGIN_ID = "com.example.thirdparty" -private const val PLUGIN_VENDOR = "PluginIndustries s.r.o." private const val MESSAGE_TEMPLATE = "Service preloading is deprecated in the <%s> element. Remove the 'preload' " + "attribute and migrate to listeners, see https://plugins.jetbrains.com/docs/intellij/plugin-listeners.html." -class ServiceExtensionPointPreloadVerifierTest { - private lateinit var verifier: ServiceExtensionPointPreloadVerifier - - private lateinit var problems: MutableList - - private val problemRegistrar = ProblemRegistrar { - problems += it - } - - @Before - fun setUp() { - verifier = ServiceExtensionPointPreloadVerifier() - problems = mutableListOf() - } - +class ServiceExtensionPointPreloadVerifierTest : + BaseExtensionPointTest(ServiceExtensionPointPreloadVerifier()) { @Test fun `has a single project service that is preloaded`() { diff --git a/intellij-plugin-structure/tests/src/test/kotlin/com/jetbrains/plugin/structure/intellij/verifiers/StatusBarWidgetFactoryExtensionPointVerifierTest.kt b/intellij-plugin-structure/tests/src/test/kotlin/com/jetbrains/plugin/structure/intellij/verifiers/StatusBarWidgetFactoryExtensionPointVerifierTest.kt index c454de54b..8b818c842 100644 --- a/intellij-plugin-structure/tests/src/test/kotlin/com/jetbrains/plugin/structure/intellij/verifiers/StatusBarWidgetFactoryExtensionPointVerifierTest.kt +++ b/intellij-plugin-structure/tests/src/test/kotlin/com/jetbrains/plugin/structure/intellij/verifiers/StatusBarWidgetFactoryExtensionPointVerifierTest.kt @@ -1,35 +1,18 @@ package com.jetbrains.plugin.structure.intellij.verifiers -import com.jetbrains.plugin.structure.base.problems.PluginProblem import com.jetbrains.plugin.structure.intellij.plugin.IdePluginImpl import org.jdom2.Element import org.junit.Assert -import org.junit.Before import org.junit.Test -private const val PLUGIN_ID = "com.example.thirdparty" -private const val PLUGIN_VENDOR = "PluginIndustries s.r.o." private const val EP_IMPLEMENTATION = "com.example.MyStatusBarWidgetFactory" private const val MESSAGE_TEMPLATE = "The extension point in the element must have " + "'id' attribute set with the same value returned from the getId() method of the $EP_IMPLEMENTATION implementation." -class StatusBarWidgetFactoryExtensionPointVerifierTest { - private lateinit var verifier: StatusBarWidgetFactoryExtensionPointVerifier - - private lateinit var problems: MutableList - - private val problemRegistrar = ProblemRegistrar { - problems += it - } - - @Before - fun setUp() { - verifier = StatusBarWidgetFactoryExtensionPointVerifier() - problems = mutableListOf() - } - +class StatusBarWidgetFactoryExtensionPointVerifierTest : + BaseExtensionPointTest(StatusBarWidgetFactoryExtensionPointVerifier()) { @Test fun `status bar widget factory extension does not declare ID`() { From 469c95504eeb461687b628bee19916e3a451b3ba Mon Sep 17 00:00:00 2001 From: Robert Novotny Date: Thu, 1 Aug 2024 14:44:26 +0200 Subject: [PATCH 4/5] Improve message wording --- .../plugin/structure/intellij/problems/UnacceptableWarnings.kt | 2 +- .../intellij/verifiers/LanguageBundleEpVerifierTest.kt | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/intellij-plugin-structure/structure-intellij/src/main/java/com/jetbrains/plugin/structure/intellij/problems/UnacceptableWarnings.kt b/intellij-plugin-structure/structure-intellij/src/main/java/com/jetbrains/plugin/structure/intellij/problems/UnacceptableWarnings.kt index 3efdecf7e..f586bd7d3 100644 --- a/intellij-plugin-structure/structure-intellij/src/main/java/com/jetbrains/plugin/structure/intellij/problems/UnacceptableWarnings.kt +++ b/intellij-plugin-structure/structure-intellij/src/main/java/com/jetbrains/plugin/structure/intellij/problems/UnacceptableWarnings.kt @@ -63,7 +63,7 @@ class LanguageBundleExtensionPointIsInternal : PluginProblem() { get() = Level.UNACCEPTABLE_WARNING override val message - get() = "The extension point in the <${extensionPointName}> element is internal " + + get() = "The extension point in the <${extensionPointName}> element is marked with @ApiStatus.Internal " + "and must be used by JetBrains only." } diff --git a/intellij-plugin-structure/tests/src/test/kotlin/com/jetbrains/plugin/structure/intellij/verifiers/LanguageBundleEpVerifierTest.kt b/intellij-plugin-structure/tests/src/test/kotlin/com/jetbrains/plugin/structure/intellij/verifiers/LanguageBundleEpVerifierTest.kt index 41e4d0cbd..6a0f2632d 100644 --- a/intellij-plugin-structure/tests/src/test/kotlin/com/jetbrains/plugin/structure/intellij/verifiers/LanguageBundleEpVerifierTest.kt +++ b/intellij-plugin-structure/tests/src/test/kotlin/com/jetbrains/plugin/structure/intellij/verifiers/LanguageBundleEpVerifierTest.kt @@ -5,7 +5,7 @@ import com.jetbrains.plugin.structure.mocks.MockExtension import org.junit.Assert.assertEquals import org.junit.Test -private const val MESSAGE_TEMPLATE = "The extension point in the element is internal and must be used by JetBrains only." +private const val MESSAGE_TEMPLATE = "The extension point in the element is marked with @ApiStatus.Internal and must be used by JetBrains only." class LanguageBundleEpVerifierTest : BaseExtensionPointTest(LanguageBundleExtensionPointVerifier()) { From 24f957178d7e85f4e66cf4dee3f9488c8cef1f8f Mon Sep 17 00:00:00 2001 From: Robert Novotny Date: Thu, 1 Aug 2024 14:48:14 +0200 Subject: [PATCH 5/5] Intentionally use fully qualified names for extension points --- .../intellij/verifiers/LanguageBundleEpVerifierTest.kt | 4 ++-- .../com/jetbrains/plugin/structure/mocks/Extensions.kt | 7 +++---- 2 files changed, 5 insertions(+), 6 deletions(-) diff --git a/intellij-plugin-structure/tests/src/test/kotlin/com/jetbrains/plugin/structure/intellij/verifiers/LanguageBundleEpVerifierTest.kt b/intellij-plugin-structure/tests/src/test/kotlin/com/jetbrains/plugin/structure/intellij/verifiers/LanguageBundleEpVerifierTest.kt index 6a0f2632d..c861fabfe 100644 --- a/intellij-plugin-structure/tests/src/test/kotlin/com/jetbrains/plugin/structure/intellij/verifiers/LanguageBundleEpVerifierTest.kt +++ b/intellij-plugin-structure/tests/src/test/kotlin/com/jetbrains/plugin/structure/intellij/verifiers/LanguageBundleEpVerifierTest.kt @@ -11,7 +11,7 @@ class LanguageBundleEpVerifierTest : BaseExtensionPointTest): MockExtension { - val extensionFqn = "com.intellij.$extensionLocalName" - val element = Element(extensionFqn).apply { + fun from(fullyQualifiedName: String, vararg attributes: Pair): MockExtension { + val element = Element(fullyQualifiedName).apply { for ((attrName, attrValue) in attributes) { setAttribute(attrName, attrValue) } } - return MockExtension(extensionFqn, listOf(element)) + return MockExtension(fullyQualifiedName, listOf(element)) } } }