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);
+ }
+}