diff --git a/src/main/java/fr/adrienbrault/idea/symfony2plugin/lang/LanguageInjection.java b/src/main/java/fr/adrienbrault/idea/symfony2plugin/lang/LanguageInjection.java index 7c16b44f8..82ba10987 100644 --- a/src/main/java/fr/adrienbrault/idea/symfony2plugin/lang/LanguageInjection.java +++ b/src/main/java/fr/adrienbrault/idea/symfony2plugin/lang/LanguageInjection.java @@ -99,6 +99,10 @@ public Builder matchingMethodCallArgument(@NotNull String classFQN, @NotNull Str return matchingPattern(LanguageInjectionPatterns.getMethodCallArgumentPattern(classFQN, methodName, argumentName, argumentIndex)); } + public Builder matchingVariableAssigment(@NotNull String variableName) { + return matchingPattern(LanguageInjectionPatterns.getVariableAssignmentPattern(variableName)); + } + public LanguageInjection build() { return new LanguageInjection(languageId, prefix, suffix, StandardPatterns.or(patterns.toArray(new ElementPattern[0]))); } diff --git a/src/main/java/fr/adrienbrault/idea/symfony2plugin/lang/LanguageInjectionPatterns.java b/src/main/java/fr/adrienbrault/idea/symfony2plugin/lang/LanguageInjectionPatterns.java index ad73a71c2..2c843f8f3 100644 --- a/src/main/java/fr/adrienbrault/idea/symfony2plugin/lang/LanguageInjectionPatterns.java +++ b/src/main/java/fr/adrienbrault/idea/symfony2plugin/lang/LanguageInjectionPatterns.java @@ -92,6 +92,17 @@ public static ElementPattern getFunctionCallArgumentPatter ); } + public static ElementPattern getVariableAssignmentPattern(@NotNull String variableName) { + return PlatformPatterns.psiElement() + .withParent(PlatformPatterns + .psiElement(AssignmentExpression.class) + .withFirstChild(PlatformPatterns + .psiElement(Variable.class) + .withName(variableName) + ) + ); + } + private static class IsAnnotationProperty extends PatternCondition { @NotNull private final String classFQN; diff --git a/src/main/java/fr/adrienbrault/idea/symfony2plugin/lang/ParameterLanguageInjector.java b/src/main/java/fr/adrienbrault/idea/symfony2plugin/lang/ParameterLanguageInjector.java index 4db1a1ca5..7b99009a5 100644 --- a/src/main/java/fr/adrienbrault/idea/symfony2plugin/lang/ParameterLanguageInjector.java +++ b/src/main/java/fr/adrienbrault/idea/symfony2plugin/lang/ParameterLanguageInjector.java @@ -16,6 +16,7 @@ import java.util.Collections; import java.util.List; +@Deprecated public class ParameterLanguageInjector implements MultiHostInjector { private static final MethodMatcher.CallToSignature[] CSS_SELECTOR_SIGNATURES = { diff --git a/src/main/java/fr/adrienbrault/idea/symfony2plugin/lang/StringLiteralLanguageInjector.java b/src/main/java/fr/adrienbrault/idea/symfony2plugin/lang/StringLiteralLanguageInjector.java index afd622dc7..586df928e 100644 --- a/src/main/java/fr/adrienbrault/idea/symfony2plugin/lang/StringLiteralLanguageInjector.java +++ b/src/main/java/fr/adrienbrault/idea/symfony2plugin/lang/StringLiteralLanguageInjector.java @@ -12,9 +12,33 @@ public class StringLiteralLanguageInjector implements MultiHostInjector { + public static final String LANGUAGE_ID_CSS = "CSS"; + public static final String LANGUAGE_ID_XPATH = "XPath"; + public static final String LANGUAGE_ID_JSON = "JSON"; + public static final String LANGUAGE_ID_DQL = "DQL"; public static final String LANGUAGE_ID_EXPRESSION_LANGUAGE = "Symfony Expression Language"; private final LanguageInjection[] LANGUAGE_INJECTIONS = { + new LanguageInjection.Builder(LANGUAGE_ID_CSS) + .withPrefix("@media all { ") + .withSuffix(" }") + .matchingMethodCallArgument("\\Symfony\\Component\\DomCrawler\\Crawler", "filter", "selector", 0) + .matchingMethodCallArgument("\\Symfony\\Component\\DomCrawler\\Crawler", "children", "selector", 0) + .matchingMethodCallArgument("\\Symfony\\Component\\CssSelector\\CssSelectorConverter", "toXPath", "cssExpr", 0) + .build(), + new LanguageInjection.Builder(LANGUAGE_ID_XPATH) + .matchingMethodCallArgument("\\Symfony\\Component\\DomCrawler\\Crawler", "filterXPath", "xpath", 0) + .matchingMethodCallArgument("\\Symfony\\Component\\DomCrawler\\Crawler", "evaluate", "xpath", 0) + .build(), + new LanguageInjection.Builder(LANGUAGE_ID_JSON) + .matchingMethodCallArgument("\\Symfony\\Component\\HttpFoundation\\JsonResponse", "fromJsonString", "data", 0) + .matchingMethodCallArgument("\\Symfony\\Component\\HttpFoundation\\JsonResponse", "setJson", "json", 0) + .build(), + new LanguageInjection.Builder(LANGUAGE_ID_DQL) + .matchingMethodCallArgument("\\Doctrine\\ORM\\EntityManager", "createQuery", "dql", 0) + .matchingMethodCallArgument("\\Doctrine\\ORM\\Query", "setDQL", "dqlQuery", 0) + .matchingVariableAssigment("dql") + .build(), new LanguageInjection.Builder(LANGUAGE_ID_EXPRESSION_LANGUAGE) .matchingConstructorCallArgument("\\Symfony\\Component\\ExpressionLanguage\\Expression", "expression", 0) .matchingFunctionCallArgument("\\Symfony\\Component\\DependencyInjection\\Loader\\Configurator\\expr", "expression", 0) diff --git a/src/test/java/fr/adrienbrault/idea/symfony2plugin/tests/lang/ParameterLanguageInjectorTest.java b/src/test/java/fr/adrienbrault/idea/symfony2plugin/tests/lang/ParameterLanguageInjectorTest.java index dd1598d90..615d5d1e3 100644 --- a/src/test/java/fr/adrienbrault/idea/symfony2plugin/tests/lang/ParameterLanguageInjectorTest.java +++ b/src/test/java/fr/adrienbrault/idea/symfony2plugin/tests/lang/ParameterLanguageInjectorTest.java @@ -6,9 +6,12 @@ import com.jetbrains.php.lang.PhpFileType; import fr.adrienbrault.idea.symfony2plugin.tests.SymfonyLightCodeInsightFixtureTestCase; import junit.framework.TestCase; +import org.junit.Ignore; import static fr.adrienbrault.idea.symfony2plugin.lang.ParameterLanguageInjector.*; +@Deprecated +@Ignore("ParameterLanguageInjectorTest is deprecated") public class ParameterLanguageInjectorTest extends SymfonyLightCodeInsightFixtureTestCase { private InjectionTestFixture injectionTestFixture; diff --git a/src/test/java/fr/adrienbrault/idea/symfony2plugin/tests/lang/StringLiteralLanguageInjectorTest.java b/src/test/java/fr/adrienbrault/idea/symfony2plugin/tests/lang/StringLiteralLanguageInjectorTest.java index 183976221..3cb4dd9b3 100644 --- a/src/test/java/fr/adrienbrault/idea/symfony2plugin/tests/lang/StringLiteralLanguageInjectorTest.java +++ b/src/test/java/fr/adrienbrault/idea/symfony2plugin/tests/lang/StringLiteralLanguageInjectorTest.java @@ -1,11 +1,18 @@ package fr.adrienbrault.idea.symfony2plugin.tests.lang; +import com.intellij.psi.PsiElement; import com.intellij.testFramework.fixtures.InjectionTestFixture; import com.jetbrains.php.lang.PhpFileType; import fr.adrienbrault.idea.symfony2plugin.tests.SymfonyLightCodeInsightFixtureTestCase; +import junit.framework.TestCase; import org.jetbrains.annotations.NotNull; +import org.jetbrains.annotations.Nullable; +import static fr.adrienbrault.idea.symfony2plugin.lang.StringLiteralLanguageInjector.LANGUAGE_ID_CSS; +import static fr.adrienbrault.idea.symfony2plugin.lang.StringLiteralLanguageInjector.LANGUAGE_ID_DQL; import static fr.adrienbrault.idea.symfony2plugin.lang.StringLiteralLanguageInjector.LANGUAGE_ID_EXPRESSION_LANGUAGE; +import static fr.adrienbrault.idea.symfony2plugin.lang.StringLiteralLanguageInjector.LANGUAGE_ID_JSON; +import static fr.adrienbrault.idea.symfony2plugin.lang.StringLiteralLanguageInjector.LANGUAGE_ID_XPATH; public class StringLiteralLanguageInjectorTest extends SymfonyLightCodeInsightFixtureTestCase { @@ -22,6 +29,52 @@ public String getTestDataPath() { return "src/test/java/fr/adrienbrault/idea/symfony2plugin/tests/lang/fixtures"; } + public void skipTestCssLanguageInjections() { + // skip as we dont have CSS module in >= 2020 test builds + String base = "filter('html > body');", LANGUAGE_ID_CSS); + assertInjectedLangAtCaret(base + "$c->filter('');", LANGUAGE_ID_CSS); + assertInjectedLangAtCaret(base + "$c->children('html > body');", LANGUAGE_ID_CSS); + assertInjectedLangAtCaret(base + "$c->children('');", LANGUAGE_ID_CSS); + + base = "toXPath('html > body');", LANGUAGE_ID_CSS); + assertInjectedLangAtCaret(base + "$c->toXPath('');", LANGUAGE_ID_CSS); + } + + public void testXPathLanguageInjections() { + String base = "filterXPath('//dummy');", LANGUAGE_ID_XPATH); + assertInjectedLangAtCaret(base + "$c->filterXPath('');", LANGUAGE_ID_XPATH); + assertInjectedLangAtCaret(base + "$c->evaluate('//dummy');", LANGUAGE_ID_XPATH); + assertInjectedLangAtCaret(base + "$c->evaluate('');", LANGUAGE_ID_XPATH); + } + + public void testJsonLanguageInjections() { + String base = "');", LANGUAGE_ID_JSON); + assertInjectedLangAtCaret(base + "JsonResponse::fromJsonString('{\"foo\": }');", LANGUAGE_ID_JSON); + + base = "setJson('');", LANGUAGE_ID_JSON); + assertInjectedLangAtCaret(base + "$r->setJson('{\"foo\": }');", LANGUAGE_ID_JSON); + } + + public void testDqlLanguageInjections() { + String base = "createQuery('SELECT b FROM \\Foo\\Bar b');", LANGUAGE_ID_DQL); + assertInjectedLangAtCaret(base + "$em->createQuery('');", LANGUAGE_ID_DQL); + assertInjectedLangAtCaret(base + "$em->createQuery(<<createQuery(<<T\nAAA\n);", "SELECT"); + assertInjectedFragmentText(base + "$em->createQuery(<<<'AAA'\nSELECT a\nAAA\n);", "SELECT a"); + base = "setDQL('SELECT b FROM \\Foo\\Bar b');", LANGUAGE_ID_DQL); + assertInjectedLangAtCaret(base + "$q->setDQL('');", LANGUAGE_ID_DQL); + + assertInjectedLangAtCaret("OM \\Foo\\Bar b\");", LANGUAGE_ID_DQL); + assertInjectedLangAtCaret("\");", LANGUAGE_ID_DQL); + } + public void testExpressionLanguageLanguageInjections() { assertInjectedLangAtCaret( "');", @@ -327,8 +380,15 @@ public void testExpressionLanguageLanguageInjections() { ); } - private void assertInjectedLangAtCaret(@NotNull String configureByText, @NotNull String lang) { + private void assertInjectedLangAtCaret(@NotNull String configureByText, @Nullable String lang) { myFixture.configureByText(PhpFileType.INSTANCE, configureByText); injectionTestFixture.assertInjectedLangAtCaret(lang); } + + private void assertInjectedFragmentText(@NotNull String configureByText, String text) { + myFixture.configureByText(PhpFileType.INSTANCE, configureByText); + PsiElement injectedElement = injectionTestFixture.getInjectedElement(); + assertNotNull(injectedElement); + TestCase.assertEquals(text, injectedElement.getContainingFile().getText()); + } }