From 1c84ee481fa22bd7abeb7b2157ef83e3d4c54fa7 Mon Sep 17 00:00:00 2001 From: bohdan-harniuk Date: Thu, 24 Mar 2022 17:38:41 +0200 Subject: [PATCH 1/3] 614: Provided file path references for JS:STRING_LITERAL psi elements in the js files --- .../reference/js/JsReferenceContributor.java | 32 +++++++++++++++---- .../idea/magento2plugin/util/RegExUtil.java | 7 ++++ 2 files changed, 32 insertions(+), 7 deletions(-) diff --git a/src/com/magento/idea/magento2plugin/reference/js/JsReferenceContributor.java b/src/com/magento/idea/magento2plugin/reference/js/JsReferenceContributor.java index 787958e34..36d67c60e 100644 --- a/src/com/magento/idea/magento2plugin/reference/js/JsReferenceContributor.java +++ b/src/com/magento/idea/magento2plugin/reference/js/JsReferenceContributor.java @@ -1,35 +1,53 @@ -/** +/* * Copyright © Magento, Inc. All rights reserved. * See COPYING.txt for license details. */ + package com.magento.idea.magento2plugin.reference.js; +import static com.intellij.patterns.StandardPatterns.string; +import static com.magento.idea.magento2plugin.util.RegExUtil.JsRegex; + +import com.intellij.lang.javascript.JSTokenTypes; +import com.intellij.lang.javascript.JavascriptLanguage; import com.intellij.lang.javascript.patterns.JSPatterns; -import com.intellij.psi.*; +import com.intellij.patterns.PlatformPatterns; +import com.intellij.psi.PsiReferenceContributor; +import com.intellij.psi.PsiReferenceRegistrar; import com.magento.idea.magento2plugin.reference.provider.FilePathReferenceProvider; import com.magento.idea.magento2plugin.reference.provider.ModuleNameReferenceProvider; import com.magento.idea.magento2plugin.reference.provider.RequireJsPreferenceReferenceProvider; import com.magento.idea.magento2plugin.util.RegExUtil; import org.jetbrains.annotations.NotNull; -import static com.intellij.patterns.StandardPatterns.string; - public class JsReferenceContributor extends PsiReferenceContributor { + @Override - public void registerReferenceProviders(@NotNull PsiReferenceRegistrar registrar) { + public void registerReferenceProviders(final @NotNull PsiReferenceRegistrar registrar) { registrar.registerReferenceProvider( JSPatterns.jsLiteralExpression() .withText(string().matches(".*" + RegExUtil.Magento.MODULE_NAME + ".*")), new ModuleNameReferenceProvider() ); + // Targets property value -> {test: 'Sandbox_Test/js/test'} registrar.registerReferenceProvider( - JSPatterns.jsLiteralExpression().withText(string().matches(".*\\W" + RegExUtil.FILE_PATH + ".*")), + JSPatterns.jsLiteralExpression() + .withText(string().matches(JsRegex.FILE_PATH)), + new FilePathReferenceProvider() + ); + + // Targets property key (JS:STRING_LITERAL) -> {'Sandbox_Test/js/test': true} + registrar.registerReferenceProvider( + PlatformPatterns.psiElement(JSTokenTypes.STRING_LITERAL) + .withText(string().matches(JsRegex.FILE_PATH)) + .withLanguage(JavascriptLanguage.INSTANCE), new FilePathReferenceProvider() ); registrar.registerReferenceProvider( - JSPatterns.jsLiteralExpression().withText(string().matches(".*\\W" + RegExUtil.FILE_PATH + ".*")), + JSPatterns.jsLiteralExpression() + .withText(string().matches(".*\\W" + RegExUtil.FILE_PATH + ".*")), new RequireJsPreferenceReferenceProvider() ); } diff --git a/src/com/magento/idea/magento2plugin/util/RegExUtil.java b/src/com/magento/idea/magento2plugin/util/RegExUtil.java index 2603d8b4b..17dd76d9d 100644 --- a/src/com/magento/idea/magento2plugin/util/RegExUtil.java +++ b/src/com/magento/idea/magento2plugin/util/RegExUtil.java @@ -103,6 +103,13 @@ public static class XmlRegex { "\\\\?" + PhpRegex.FQN + "(" + CLASS_MEMBER_NAME + ")?.*"; } + public static class JsRegex { + + // Targets paths like `'Sandbox_Test/js/test'` + public static final String FILE_PATH + = "(\\W{1}[A-Z][a-zA-Z0-9]+_[A-Z][a-zA-Z0-9]+[\\/\\w*-]{1,}\\W{1})"; + } + public static class CustomTheme { public static final String MODULE_NAME = "app\\/design\\/(adminhtml|frontend)\\/\\w*\\/\\w*\\/\\w*"; From db73a4ce075a79dc69727ec19cdea75519d0a999 Mon Sep 17 00:00:00 2001 From: bohdan-harniuk Date: Thu, 24 Mar 2022 18:00:05 +0200 Subject: [PATCH 2/3] 614: Code refactoring --- .../js/RequireJsReferenceRegistrarTest.java | 27 +++++++++++++------ 1 file changed, 19 insertions(+), 8 deletions(-) diff --git a/tests/com/magento/idea/magento2plugin/reference/js/RequireJsReferenceRegistrarTest.java b/tests/com/magento/idea/magento2plugin/reference/js/RequireJsReferenceRegistrarTest.java index 666b3b35d..195c927cf 100644 --- a/tests/com/magento/idea/magento2plugin/reference/js/RequireJsReferenceRegistrarTest.java +++ b/tests/com/magento/idea/magento2plugin/reference/js/RequireJsReferenceRegistrarTest.java @@ -2,34 +2,45 @@ * Copyright © Magento, Inc. All rights reserved. * See COPYING.txt for license details. */ + package com.magento.idea.magento2plugin.reference.js; public class RequireJsReferenceRegistrarTest extends ReferenceJsFixtureTestCase { + private static final String FIXTURE_PATH = "test.js"; + + /** + * Mapped parameters should have reference to file. + */ public void testMappedInjectionParameterMustHaveReference() { - String filePath = this.getFixturePath("test.js"); - myFixture.configureByFile(filePath); + myFixture.configureByFile(getFixturePath(FIXTURE_PATH)); assertHasReferenceToFile("app/code/Foo/Bar/view/frontend/web/js/file.js"); } + /** + * Path parameters should have reference to file. + */ public void testPathInjectionParameterMustHaveReference() { - String filePath = this.getFixturePath("test.js"); - myFixture.configureByFile(filePath); + myFixture.configureByFile(getFixturePath(FIXTURE_PATH)); assertHasReferenceToFile("app/code/Foo/Bar/view/frontend/web/js/file2.js"); } + /** + * The Magento resource file path parameters should have reference to file. + */ public void testFileInjectionParameterMustHaveReference() { - String filePath = this.getFixturePath("test.js"); - myFixture.configureByFile(filePath); + myFixture.configureByFile(getFixturePath(FIXTURE_PATH)); assertHasReferenceToFile("app/code/Foo/Bar/view/frontend/web/js/file.js"); } + /** + * Lib resource parameters should have reference to file. + */ public void testLibInjectionParameterMustHaveReference() { - String filePath = this.getFixturePath("test.js"); - myFixture.configureByFile(filePath); + myFixture.configureByFile(getFixturePath(FIXTURE_PATH)); assertHasReferenceToFile("/lib/web/testjs.js"); } From df473c99522234afc0c4c7fffca6aec23914914d Mon Sep 17 00:00:00 2001 From: bohdan-harniuk Date: Fri, 25 Mar 2022 11:42:23 +0200 Subject: [PATCH 3/3] 614: Added test coverage --- .../requirejs-config.js | 9 ++++ .../reference/BaseReferenceTestCase.java | 47 ++++++++++++++++++- .../js/RequireJsReferenceRegistrarTest.java | 15 ++++++ 3 files changed, 70 insertions(+), 1 deletion(-) create mode 100644 testData/reference/js/RequireJsReferenceRegistrar/filePathInMixinDeclarationMustHaveReference/requirejs-config.js diff --git a/testData/reference/js/RequireJsReferenceRegistrar/filePathInMixinDeclarationMustHaveReference/requirejs-config.js b/testData/reference/js/RequireJsReferenceRegistrar/filePathInMixinDeclarationMustHaveReference/requirejs-config.js new file mode 100644 index 000000000..f4f72ba67 --- /dev/null +++ b/testData/reference/js/RequireJsReferenceRegistrar/filePathInMixinDeclarationMustHaveReference/requirejs-config.js @@ -0,0 +1,9 @@ +var config = { + config: { + mixins: { + 'Magento_Checkout/js/view/shipping': { + 'Foo_Bar/js/file': true + } + } + } +} diff --git a/tests/com/magento/idea/magento2plugin/reference/BaseReferenceTestCase.java b/tests/com/magento/idea/magento2plugin/reference/BaseReferenceTestCase.java index 560e685bb..4f50d8333 100644 --- a/tests/com/magento/idea/magento2plugin/reference/BaseReferenceTestCase.java +++ b/tests/com/magento/idea/magento2plugin/reference/BaseReferenceTestCase.java @@ -9,11 +9,13 @@ import com.intellij.psi.PsiElement; import com.intellij.psi.PsiFile; import com.intellij.psi.PsiReference; +import com.intellij.psi.PsiReferenceProvider; import com.intellij.psi.ResolveResult; import com.intellij.psi.impl.file.PsiDirectoryImpl; import com.intellij.psi.xml.XmlAttributeValue; import com.intellij.psi.xml.XmlFile; import com.intellij.psi.xml.XmlTag; +import com.intellij.util.ProcessingContext; import com.jetbrains.php.lang.psi.elements.Method; import com.jetbrains.php.lang.psi.elements.Parameter; import com.jetbrains.php.lang.psi.elements.ParameterList; @@ -21,6 +23,10 @@ import com.magento.idea.magento2plugin.inspections.BaseInspectionsTestCase; import com.magento.idea.magento2plugin.magento.packages.File; import com.magento.idea.magento2plugin.reference.xml.PolyVariantReferenceBase; +import java.lang.reflect.InvocationTargetException; +import java.util.ArrayList; +import java.util.Arrays; +import java.util.List; import org.jetbrains.annotations.Nullable; @SuppressWarnings({ @@ -36,6 +42,7 @@ protected void setUp() throws Exception { myFixture.setTestDataPath(testDataFolderPath); } + @SuppressWarnings("PMD.CognitiveComplexity") protected void assertHasReferenceToXmlAttributeValue(final String reference) { final PsiElement element = getElementFromCaret(); for (final PsiReference psiReference: element.getReferences()) { @@ -70,6 +77,7 @@ protected void assertHasReferenceToXmlAttributeValue(final String reference) { fail(String.format(referenceNotFound, reference)); } + @SuppressWarnings("PMD.CognitiveComplexity") protected void assertHasReferenceToXmlTag(final String tagName) { final PsiElement element = getElementFromCaret(); for (final PsiReference psiReference: element.getReferences()) { @@ -106,7 +114,40 @@ protected void assertHasReferenceToXmlTag(final String tagName) { protected void assertHasReferenceToFile(final String reference) { final PsiElement element = getElementFromCaret(); - for (final PsiReference psiReference : element.getReferences()) { + + assertHasReferenceToFile(reference, Arrays.asList(element.getReferences())); + } + + protected void assertHasReferenceToFile( + final String reference, + final Class providerClass + ) { + final PsiElement element = getLeafElementFromCaret(); + final List references = new ArrayList<>(); + + try { + final PsiReferenceProvider provider = providerClass.getConstructor().newInstance(); + references.addAll( + Arrays.asList( + provider.getReferencesByElement(element, new ProcessingContext()) + ) + ); + } catch (NoSuchMethodException + | IllegalAccessException + | InvocationTargetException + | InstantiationException exception + ) { + references.addAll(Arrays.asList(element.getReferences())); + } + + assertHasReferenceToFile(reference, references); + } + + protected void assertHasReferenceToFile( + final String reference, + final List references + ) { + for (final PsiReference psiReference : references) { final PsiElement resolved = psiReference.resolve(); if (!(resolved instanceof PsiFile)) { continue; @@ -250,4 +291,8 @@ protected void assertEmptyReference() { private PsiElement getElementFromCaret() { return myFixture.getFile().findElementAt(myFixture.getCaretOffset()).getParent(); } + + private PsiElement getLeafElementFromCaret() { + return myFixture.getFile().findElementAt(myFixture.getCaretOffset()); + } } diff --git a/tests/com/magento/idea/magento2plugin/reference/js/RequireJsReferenceRegistrarTest.java b/tests/com/magento/idea/magento2plugin/reference/js/RequireJsReferenceRegistrarTest.java index 195c927cf..0ecb6f720 100644 --- a/tests/com/magento/idea/magento2plugin/reference/js/RequireJsReferenceRegistrarTest.java +++ b/tests/com/magento/idea/magento2plugin/reference/js/RequireJsReferenceRegistrarTest.java @@ -5,9 +5,12 @@ package com.magento.idea.magento2plugin.reference.js; +import com.magento.idea.magento2plugin.reference.provider.FilePathReferenceProvider; + public class RequireJsReferenceRegistrarTest extends ReferenceJsFixtureTestCase { private static final String FIXTURE_PATH = "test.js"; + private static final String MIXIN_FIXTURE_PATH = "requirejs-config.js"; /** * Mapped parameters should have reference to file. @@ -44,4 +47,16 @@ public void testLibInjectionParameterMustHaveReference() { assertHasReferenceToFile("/lib/web/testjs.js"); } + + /** + * Mixin declaration parameters should have reference to file. + */ + public void testFilePathInMixinDeclarationMustHaveReference() { + myFixture.configureByFile(getFixturePath(MIXIN_FIXTURE_PATH)); + + assertHasReferenceToFile( + "app/code/Foo/Bar/view/frontend/web/js/file.js", + FilePathReferenceProvider.class + ); + } }