From c468cbce3059b2fe582f0e055bf04e952054d6aa Mon Sep 17 00:00:00 2001 From: Cedric Ziel Date: Thu, 7 Jun 2018 00:10:11 +0200 Subject: [PATCH] Inject TypoScript Language in String arguments Closes: #169 --- .travis.yml | 3 +- build.gradle | 2 +- gradle.properties | 5 +- .../typo3/injection/TypoScriptInjector.java | 68 +++++++++++++++++++ src/main/resources/META-INF/plugin.xml | 2 + .../resources/META-INF/typoscript-plugin.xml | 7 ++ .../injection/TypoScriptInjectorTest.java | 13 ++++ 7 files changed, 96 insertions(+), 4 deletions(-) create mode 100644 src/main/java/com/cedricziel/idea/typo3/injection/TypoScriptInjector.java create mode 100644 src/main/resources/META-INF/typoscript-plugin.xml create mode 100644 src/test/java/com/cedricziel/idea/typo3/injection/TypoScriptInjectorTest.java diff --git a/.travis.yml b/.travis.yml index 0f080a32..7b5d51e2 100644 --- a/.travis.yml +++ b/.travis.yml @@ -16,7 +16,7 @@ cache: matrix: include: - - env: IDEA_VERSION="IU-182.2757.3" PHP_PLUGIN_VERSION="182.2574.13" DEPLOY=true + - env: IDEA_VERSION="IU-182.2949.4" PHP_PLUGIN_VERSION="182.2949.27" TYPOSCRIPT_PLUGIN_VERSION="1.9.0" DEPLOY=true # - env: IDEA_VERSION="IU-173.4127.17" PHP_PLUGIN_VERSION="173.4127.13" # allow_failures: # - env: IDEA_VERSION="IU-173.4127.17" PHP_PLUGIN_VERSION="173.4127.13" @@ -25,6 +25,7 @@ before_install: - "export ORG_GRADLE_PROJECT_ideaVersion=${IDEA_VERSION}" - "export ORG_GRADLE_PROJECT_ideaType=${IDEA_TYPE}" - "export ORG_GRADLE_PROJECT_phpPluginVersion=${PHP_PLUGIN_VERSION}" +- "export ORG_GRADLE_PROJECT_typoScriptPluginVersion=${TYPOSCRIPT_PLUGIN_VERSION}" - java -version script: diff --git a/build.gradle b/build.gradle index 0494af35..466ff92d 100644 --- a/build.gradle +++ b/build.gradle @@ -21,7 +21,7 @@ apply plugin: 'java' intellij { version ideaVersion pluginName 'TYPO3 CMS Plugin' - plugins = ["com.jetbrains.php:${phpPluginVersion}", 'CSS', 'java-i18n', 'properties', 'yaml'] + plugins = ["com.jetbrains.php:${phpPluginVersion}", "de.sgalinski.typoscript.plugin.id:${typoScriptPluginVersion}", 'CSS', 'java-i18n', 'properties', 'yaml', 'IntelliLang'] downloadSources !Boolean.valueOf(System.getenv('CI')) publishPlugin { diff --git a/gradle.properties b/gradle.properties index 47e7444b..df21bd81 100644 --- a/gradle.properties +++ b/gradle.properties @@ -1,5 +1,6 @@ -ideaVersion = IU-182.2757.3 -phpPluginVersion = 182.2574.13 +ideaVersion = IU-182.2949.4 +phpPluginVersion = 182.2949.27 +typoScriptPluginVersion = 1.9.0 #ideaVersion = IU-2018.1.4 #phpPluginVersion = 181.5087.24 #ideaVersion = IU-2017.3.3 diff --git a/src/main/java/com/cedricziel/idea/typo3/injection/TypoScriptInjector.java b/src/main/java/com/cedricziel/idea/typo3/injection/TypoScriptInjector.java new file mode 100644 index 00000000..58d9a19e --- /dev/null +++ b/src/main/java/com/cedricziel/idea/typo3/injection/TypoScriptInjector.java @@ -0,0 +1,68 @@ +package com.cedricziel.idea.typo3.injection; + +import com.intellij.lang.Language; +import com.intellij.patterns.PlatformPatterns; +import com.intellij.psi.PsiElement; +import com.jetbrains.php.injection.PhpInjectorBase; +import com.jetbrains.php.lang.psi.elements.*; +import de.sgalinski.typoscript.language.TypoScriptLanguage; +import org.jetbrains.annotations.NotNull; +import org.jetbrains.annotations.Nullable; + +public class TypoScriptInjector extends PhpInjectorBase { + + public static final String[] TYPOSCRIPT_ARGUMENTS = new String[]{ + "TYPO3\\CMS\\Core\\Utility\\ExtensionManagementUtility::addPageTSConfig", + "TYPO3\\CMS\\Core\\Utility\\ExtensionManagementUtility::addUserTSConfig", + "TYPO3\\CMS\\Core\\Utility\\ExtensionManagementUtility::addTypoScriptSetup", + "TYPO3\\CMS\\Core\\Utility\\ExtensionManagementUtility::addTypoScriptConstants", + }; + + private static boolean isTypoScriptAcceptingMethod(@NotNull PsiElement psiElement) { + for (String TYPOSCRIPT_ARGUMENT : TYPOSCRIPT_ARGUMENTS) { + String[] split = TYPOSCRIPT_ARGUMENT.split("::"); + if (isStringArgumentInMethodReference(psiElement) && signatureMatches(psiElement, split[0], split[1])) { + + return true; + } + } + + return false; + } + + private static boolean signatureMatches(@NotNull PsiElement psiElement, @NotNull String className, @NotNull String methodName) { + PsiElement parent = psiElement.getParent(); + PsiElement superParent = parent.getParent(); + + MethodReference methodReference = (MethodReference) superParent; + PsiElement resolve = methodReference.resolve(); + if (!(resolve instanceof Method)) { + return false; + } + + Method method = (Method) resolve; + PhpClass containingClass = method.getContainingClass(); + + return methodReference.getName() != null && methodReference.getName().equals(methodName) + && containingClass != null && containingClass.getFQN().equals(className); + } + + private static boolean isStringArgumentInMethodReference(@NotNull PsiElement psiElement) { + + return PlatformPatterns.psiElement(StringLiteralExpression.class).withParent( + PlatformPatterns.psiElement(ParameterList.class).withParent( + PlatformPatterns.psiElement(MethodReference.class) + ) + ).accepts(psiElement); + } + + @Nullable + @Override + public Language getInjectedLanguage(@NotNull PsiElement psiElement) { + if (isTypoScriptAcceptingMethod(psiElement)) { + return TypoScriptLanguage.INSTANCE; + } + + return null; + } +} diff --git a/src/main/resources/META-INF/plugin.xml b/src/main/resources/META-INF/plugin.xml index 4c306b92..d5153a0b 100644 --- a/src/main/resources/META-INF/plugin.xml +++ b/src/main/resources/META-INF/plugin.xml @@ -133,6 +133,8 @@ It is a great inspiration for possible solutions and parts of the code.

com.jetbrains.php com.intellij.modules.xml org.jetbrains.plugins.yaml + org.intellij.intelliLang + de.sgalinski.typoscript.plugin.id diff --git a/src/main/resources/META-INF/typoscript-plugin.xml b/src/main/resources/META-INF/typoscript-plugin.xml new file mode 100644 index 00000000..80e5ba9a --- /dev/null +++ b/src/main/resources/META-INF/typoscript-plugin.xml @@ -0,0 +1,7 @@ + + + + + + + diff --git a/src/test/java/com/cedricziel/idea/typo3/injection/TypoScriptInjectorTest.java b/src/test/java/com/cedricziel/idea/typo3/injection/TypoScriptInjectorTest.java new file mode 100644 index 00000000..0e9f413b --- /dev/null +++ b/src/test/java/com/cedricziel/idea/typo3/injection/TypoScriptInjectorTest.java @@ -0,0 +1,13 @@ +package com.cedricziel.idea.typo3.injection; + +import com.cedricziel.idea.typo3.AbstractTestCase; +import de.sgalinski.typoscript.language.TypoScriptLanguage; + +public class TypoScriptInjectorTest extends AbstractTestCase { + public void testInjectsLanguagesInMethodArguments() { + myFixture.configureByText("foo.php", "\">)"); + + assertInstanceOf(myFixture.getElementAtCaret().getLanguage(), TypoScriptLanguage.class); + } +}